如何在 Symfony 2.1 的 FormEvent 中更新 ChoiceType 的值?

问题描述 投票:0回答:2

我想我可能需要扩展 LazyChoiceList 并实现一个新的 FormType,到目前为止我已经:

/**
 * 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 没有效果,因为它已经已处理。

php symfony-forms symfony-2.1
2个回答
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;

这是因为在构建表单时,事件似乎被多次触发。 我在您发布的代码中没有看到等效的行。

© www.soinside.com 2019 - 2024. All rights reserved.