声明Symfony表单选项(Sym 2.8 / 3.0)

时间:2016-01-27 23:13:33

标签: symfony-forms symfony symfony-2.8

我正在寻找在表单中创建/添加动态选项的最佳方法。通过选项,我的意思是选择值对,甚至可能是默认值。我至少可以看到三个选项:

1)添加表单类型时,将选项添加到$options数组。为此,我必须首先声明一个默认值,然后将它们添加到add方法和控制器中:

控制器:

    $choices = [];
    foreach ($pages as $page) {
        $choices[$page->getId()] = $page->getTitle();
    }
    $options = ['pages' => $choices];
    $form = $this->createForm('MyBundle\Form\Type\PageType', $data, $options);

FormType:

class PageType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('pid', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', [
                'choices' => $options['pages'],
                'label' => __('Page')
            ]);
    }
...
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'pages' => []
        ]);
    }
}

2)如果值不依赖于控制器值,我似乎可以在OptionsResolver中创建它们(假设访问源数据)

FormType:

class PageType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('pid', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', [
                'choices' => $options['pages'],
                'label' => __('Page')
            ]);
    }
...
    public function configureOptions(OptionsResolver $resolver)
    {
        $choices = [];
        $pages = $this->getPages();
        foreach ($pages as $page) {
            $choices[$page->getId()] = $page->getTitle();
        }

        $resolver->setDefaults([
            'pages' => $choices
        ]);
    }

3)最后,我还可以添加buildForm方法(再次假设访问源数据):

FormType:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $choices = [];
        $pages = $this->getPages();
        foreach ($pages as $page) {
            $choices[$page->getId()] = $page->getTitle();
        }

        $builder
            ->add('pid', 'Symfony\Component\Form\Extension\Core\Type\ChoiceType', [
                'choices' => $choices,
                'label' => __('Page')
            ]);
    }

显然,第一个选项具有最大的灵活性,但如果我不需要这种灵活性,或者由于某些原因不想管理控制器中的选项,那么在buildFormconfigureOptions方法?

2 个答案:

答案 0 :(得分:2)

如果您需要灵活性,则无法使用解决方案3.但如果您想避免灵活性,那么解决方案3是最好的。

解决方案1和2都可以,它实际上取决于您的需求:

  • 如果您在多个具有不同选择的操作中使用表单:使用解决方案1,但在此选项上添加一个要求以防止在没有选择的情况下调用表单
  • 如果您的选择通常相同,但有时只想覆盖它们:选择解决方案2

我个人更喜欢解决方案1,因为如果您的表单依赖于可能性较小的外部对象(示例中为$this->pages),它总是更好。

此致

答案 1 :(得分:1)

如果您使用Doctrine Entities,您应该使用:

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
// ...

$builder->add('pid', EntityType::class, array(
    'class' => 'AppBundle:Page',
    'choice_label' => 'title',
));

使用另一种类型的对象:

use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use AppBundle\Entity\Page;
// ...

$builder->add('pid', ChoiceType::class, [
    'choices' => [
        new Page('Page 1'),
        new Page('Page 2'),
        new Page('Page 3'),
        new Page('Page 4'),
    ],
    'choices_as_values' => true,
    'choice_label' => function($page, $key, $index) {
        /** @var Page $page */
        return $page->getTitle();
    }
]);

您可以在blog post here中阅读更多信息。