0

我想我可能需要扩展 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 无效,据我所知,因为它已经处理。

4

2 回答 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

于 2012-08-10T15:19:26.147 回答
1

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

该示例具有:

if (!$data) return;

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

于 2012-08-10T15:19:39.547 回答