2016-04-01 4 views
1

特定のエンティティの複数のレコードを作成するフォームタイプを作成する必要があります。Symfony2は、同じタイプの複数のレコードを追加するフォームタイプを作成します。

私は親のフォームタイプを作成してからコレクションを追加することにしました。この親Typeはどのエンティティにもバインドされませんが、子Typeはバインドされます。問題は、リクエストを処理すると、空のデータオブジェクトが取得されることです。ここで

は私の親のタイプである:

class ChallengeCollectionType extends AbstractType { 

    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('email_invitations', CollectionType::class, [ 
      'entry_type' => EmailInvitationType::class 
     ]); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'csrf_protection' => false 
     )); 
    } 

} 

私の子供のタイプ:

class EmailInvitationType extends AbstractType { 

    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('email', EmailType::class); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class'  => Challenge::class, 
      'csrf_protection' => false 
     )); 
    } 

} 

ここでは、私はコントローラに私のデータを処理する方法である:

public function inviteEmailAction(Request $request){ 

     $form = $this->createForm(ChallengeCollectionType::class); 

     $form->handleRequest($request); 

     dump($form->getData()); 
     dump($form->get('email_invitations')->getData()); 
     die(); 
} 

私はAのデータを提出しますPOSTリクエスト(これはAPIでHTMLフォームはありません):

challenge_collection[email_invitations][0][email] = "[email protected]" 
challenge_collection[email_invitations][1][email] = "[email protected]" 

コントローラは、すべてのダンプに対してempty []を返します。

私が実際に回避策を見つけたが、それは悪いなります

 $data = ['email_invitations' => [new Challenge(), new Challenge()]];   

     $form = $this->createForm(ChallengeCollectionType::class, $data); 

     $form->handleRequest($request); 

そして、これは動作しますので、私は、要求が処理され得るために、エンティティのタイプの空のオブジェクトの配列を送信する必要があります。

、あるいはこのよう:

$data = ['email_invitations' => []]; 

    if(!empty($request->request->get('challenge_collection'))){ 
     if(!empty($request->request->get('challenge_collection')['email_invitations'])){ 
      for($i = 0; $i < count($request->request->get('challenge_collection')['email_invitations']); $i ++){ 
       $data['email_invitations'][] = new Challenge(); 
      } 
     } 
    } 

それを行うには良い方法があるはずです、私はそれを見つけるために助けてください。

答えて

0

たぶん、あなたはあなたのコントローラで試してみてくださいのようなもの:

$invitations = $this->getDoctrine()->getRepository('yourInvitationEntityClass')->findAll());   
$form = $this->createForm(ChallengeCollectionType::class, $invitations); 

あなたがここでの説明を見つけることができる:

http://symfony.com/doc/current/cookbook/form/form_collections.html

One form with all row of one entity

+0

ありがとうございました!私の懸念は、この場合のfindAll()は何千ものレコードを返すことができるということです。実際には使用しないデータを得るためにデータベースに重い要求を実行するのは良い方法ですか?この場合、空のエンティティのセットを作成する私のサイクルはより効率的に見える –

+0

こんにちは@Vladimir Mikhaylovskiy findAll()は単なる例でした。リポジトリで独自のリクエストを作成して使用することができます。それを行うには良い方法ではなく、効果的に新しいものを創り出すことだけであれば、c)。この場合、Prototypeを試してみるべきです:http://symfony.com/doc/current/cookbook/form/form_collections.html#allowing-new-tags-with-the-prototype – lemairep

+0

私が理解するように、Prototypeは私はAPIを構築しているので、私はそれについて心配していません。タグを含む例では、エンティティに関連するすべてのタグを返すgetTags()があります。しかし、私は私の場合、エンティティを持っていません。 –

1

をあなたは中allow_addallow_deleteオプションを使用してみてくださいコレクションフィールドタイプ。 See the Collection field type documentation

子エンティティとの関連付けを持つことが重要です。コントローラ内のArrayCollectionオブジェクトに子オブジェクトが追加されます。

また、リクエストごとに自動的に保存/削除する場合は、 'by_reference false and set association with cascade-persist and cascade-remove`を実装する必要があります。

APIを使用してフィールドタイプを何度も使用していて、魅力的でした。それ以上の説明が必要な場合はお知らせください。

関連する問題