2012-08-10 29 views
0

我想我可能需要延长LazyChoiceList和实施新的FormType,所以到目前为止,我有:如何在Symfony 2.1的FormEvent中更新ChoiceType的值?

/** 
* A choice list for sorting choices. 
*/ 
class SortChoiceList extends LazyChoiceList 
{ 
    private $choices = array(); 

    public function getChoices() { 
     return $this->choices; 
    } 

    public function setChoices(array $choices) { 
     $this->choices = $choices; 
     return $this; 
    } 

    protected function loadChoiceList() { 
     return new SimpleChoiceList($this->choices); 
    } 
} 

/** 
* @FormType 
*/ 
class SortChoice extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->getParent()->addEventListener(FormEvents::PRE_SET_DATA, function($event) use ($options) { 
      $options = (object) $options; 

      $list = $options->choice_list; 

      $data = $event->getData(); 

      if ($data->getLocation() && $data->getDistance()) { 
       $list->setChoices(array(
        '' => 'Distance', 
        'highest' => 'Highest rated', 
        'lowest' => 'Lowest rated' 
       )); 
      } else { 
       $list->setChoices(array(
        '' => 'Highest rated', 
        'lowest' => 'Lowest rated' 
       )); 
      } 
     }); 
    } 

    public function getParent() 
    { 
     return 'choice'; 
    } 

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

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'choice_list' => new SortChoiceList 
     )); 
    } 
} 

我试过这种方法对所有的可用的FormEvent的,但我没有访问数据(空值)或更新choice_list没有效果,据我所知,因为它已经被处理。

回答

1

原来我并不需要在所有定义一个新类型或LazyList和更好的做法是,直到我有数据,在我的主要形式,像这样不加场:

$builder->addEventListener(FormEvents::PRE_BIND, function($event) use ($builder) { 
    $form = $event->getForm(); 
    $data = (object) array_merge(array('location' => null, 'distance' => null, 'sort_by' => null), $event->getData()); 

    if ($data->location && $data->distance) { 
     $choices = array(
      '' => 'Distance', 
      'highest' => 'Highest rated', 
      'lowest' => 'Lowest rated' 
     ); 
    } else { 
     $choices = array(
      '' => 'Highest rated', 
      'lowest' => 'Lowest rated' 
     ); 
    } 

    $form->add($builder->getFormFactory()->createNamed('sort_by', 'choice', $data->sort_by, array(
     'choices' => $choices, 
     'required' => false 
    ))); 
}); 

见:http://symfony.com/doc/master/cookbook/form/dynamic_form_generation.html

1

你读过这个:http://symfony.com/doc/master/cookbook/form/dynamic_form_generation.html

的例子有:

if (!$data) return; 

而这是因为这些事件似乎在窗体被构建时被多次触发。我在您的发布代码中没有看到相应的行。

+0

我已经看到,是的,事实上我在我的回答中引用了它,它在我的示例中有特征,但在我的情况下,对于这种形式,空值永远不会传递,所以为了简单。 – Steve 2012-08-13 10:10:34