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でこの種のアプローチを試しましたが、データ(null値)にアクセスできないか、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 に答える