2016-08-15 24 views
0

私はSymfony 2.7で作業しています。 FormEventハンドラの情報をbuildViewメソッドに渡すことはどういうことですか?FormEventからbuildViewメソッドに設定/オプションを渡す

私はデータをチェックするために FormEvents::PRE_SET_DATAを使用し、その結果に応じて、 buildViewににformTypeにいくつかのオプション/情報を追加したいと思います

class MyEntitiesType extends AbstractType { 
    ... 
    public function getParent() { 
     return 'entity'; 
    } 

    public function getName() { 
     return 'my_entities_type'; 
    } 

    private $globalVar = false; 

    public function buildForm(FormBuilderInterface $builder, array $options) { 
     $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) { 
      $data = $event->getData(); 

      // $data is an array of myEntity. Check in some 
      // 'special' myEntity instances are included. Remove 
      // these instances from the data/selection and remember 
      // this to update the view in buildView 

      if (someSpecialEntitiesUsed($data)) { 
       $data = removeSpecialEntities($data); 

       // Will work but will deliver false results, since 
       // there is only one instance for all MyEntitiesTypes 
       // within the form 
       $this->globalVar = true; 

       // Will not work, since array is not passed by reference 
       // ==> global version of $options is not updated 
       // $options['specialDataUsed'] = true; 

       // Would be a good solution but so such methode... 
       $builder->setSomeOptions(...) 

       // EntityType will only accept managed objects as 
       // data. I do not want to add data but only config information 
       $data[] = $someSpecialDataObject; 

       $event->setData($data); 
      } 
     } 
     ... 
    } 

    public function buildView(FormView $view, FormInterface $form, array $options) { 
     $data = $view->vars['data']; 

     // This will return false, since the special entities 
     // have already been filtered out in buildForm 
     someSpecialEntitiesUsed($data) 

     // How to get the information, that entities have been 
     // filtered out? 
     $entitiesFiltered = ...; 

     if (entitiesFiltered) { 
      $view->vars['show_hint'] = true; 
      ... 
     } 
    } 
} 

私はすでにからのフィルタリングエンティティに関する情報を渡すためにさまざまなオプションを試してみましたbuildFormbuildView(上記参照)、いずれも機能しませんでした。

どういうわけかできますか?もちろん

私は私にformType実装にしてチェックsomeSpecialEntitiesUsed($data)ではなく実行し、代わりにフォーム内:

class MyForm extends AbstractType { 
    ... 

    public function getName() { 
     return 'my_form'; 
    } 

    public function buildForm(FormBuilderInterface $builder, array $options) { 
     $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { 
      $entities = $event->getData(); 
      $form = $event->getForm(); 

      $used = someSpecialEntitiesUsed($data) 

      $form 
       ->add('entities', 'my_entities_type', array(
        ... 
        'specialDataUsed' => used, 
        ..., 
       )); 
      }); 
     } 
    } 

しかし、この溶液中で、私はかなりあるmy_entities_typeを使用すべてのフォームを更新する必要がありますたくさん。さらに、このロジックはmy_entities_typeに属し、このタイプを使用しているフォームには属しません。だからmy_entities_typeのための解決策を見つけることは、もっときれいになるでしょう...

答えて

0

私はこの質問に正確な答えはありませんが、私はフォームコンポーネントのいくつかのロジックに従おうとします。

まず最初に、イベントリスナーの主な仕事は常にデータではなくフォームを変更することでした。そして、あなたはこのロジックをいくつかのエンティティを削除するブレーキをかけている。

もう1つのことは、フォームの構成(FormConfig)は大声で "私に変更を依頼しないでください"と書かれているということです。だから私たちは良くしないでしょう。

また、フォームにバインドされたデータを変更するには、DataTransformerが必要です。

この論理と目標に沿って、my_entities_type_filteredのように呼び出され、不要なデータを削除するDataTransformerを追加する別のフォームを作成することをお勧めします。したがって、この内部のmy_entities_type_filteredmy_entities_typeに追加し、使用できるフラグをbuildViewにすることができます。

<?php 
//... 
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {  
    $data = $event->getData(); 
    $specialEntitiesUsed = someSpecialEntitiesUsed($data); 
    $form = $event->getForm(); 
    $form->add('someinnerfieldname', MyEntitiesType::class, [ 
     'property_path' => $form->getPropertyPath(), // if this won't work as expected you should add data transformer to this form also. 
     'special' => $specialEntitiesUsed 
    ]); 
関連する問題