7

我正在使用表单类在我的项目中构建各种表单。

在 Entity Type 文件中,对于 buildForm 函数,有一个“array $options”的辅助参数(这在官方 Symfony 2 文档中显示,但从未提及过!)

我已经将一个数组输入到控制器中的 createForm 函数中,但现在我完全不知道如何检索存储的值?

$form = $this->createForm(new ProductType(array(), array('id' => '2')), $product);

关于获取选项,我发现的唯一一件事是使用 getOption() 函数,但这在 Symfony 2 中不存在(我发现的帖子来自 2010 年)。

我尝试使用:

$id = $options['id'];

但是当我尝试在任何地方使用 $id 时,我得到了错误:

注意:未定义索引:id

是什么赋予了?

如何从 $options 数组中检索我的值?我什至一开始就正确设置它们吗?

编辑 - 更多代码:

表单类

<?php

namespace DEMO\DemoBundle\Form\Product;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ProductType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('slug')
            ->add('reference')
            ->add('description')
            ->add('active_from')
            ->add('active_till')
            ->add('is_active')
            ->add('category', 'entity', array(
                'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory',
                'query_builder' => function(EntityRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->where('u.section = :id')
                        ->setParameter('id', ***ID VARIABLE NEEDS TO GO HERE***)
                        ->orderBy('u.root', 'ASC')
                        ->addOrderBy('u.lft', 'ASC');
                },
                'empty_value' => 'Choose an option',
                'property' => 'indentedName',
            ));
    }

    public function getDefaultOptions()
    {
        return array(
            'data_class' => 'DEMO\DemoBundle\Entity\Product\Product'
        );
    }

    public function getName()
    {
        return 'demo_demobundle_product_type';
    }
}
4

6 回答 6

17

我认为您一开始就没有正确设置它们。你应该把它们作为第三个参数createForm()

编辑:这是您的表单类的外观:

<?php
namespace DEMO\DemoBundle\Form\Product;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ProductType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('slug')
            ->add('reference')
            ->add('description')
            ->add('active_from')
            ->add('active_till')
            ->add('is_active')
            ->add('category', 'entity', array(
                'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory',
                'query_builder' => function(EntityRepository $er) use($options) {
                    return $er->createQueryBuilder('u')
                        ->where('u.section = :id')
                        ->setParameter('id', $options['id'])
                        ->orderBy('u.root', 'ASC')
                        ->addOrderBy('u.lft', 'ASC');
                },
                'empty_value' => 'Choose an option',
                'property' => 'indentedName',
            ));
    }

    public function getDefaultOptions()
    {
        return array(
            'data_class' => 'DEMO\DemoBundle\Entity\Product\Product',
            'id'         => null
        );
    }

    public function getName()
    {
        return 'demo_demobundle_product_type';
    }
}
于 2012-04-30T14:32:20.477 回答
9

让我告诉你什么对我有用

在控制器中:

$form = $this->createForm(new UsersType(), $entity, array(
    'attr' => array('locationId' => $currentLocationId)));

在表单类型中:

->add('location', 'entity', array(
        'class' => 'Ro\RoinventBundle\Entity\Locations',
         'query_builder' => function (\Doctrine\ORM\EntityRepository $er) use ($options)
        {
            if (isset($options['attr']['locationId']) && ($options['attr']['locationId'] != NULL))
            {
                return $er->createQueryBuilder('Locations')
                    ->where('Locations.id = :param')
                    ->setParameter('param', $options['attr']['locationId']);
            }
            //else do what you want
},
));
于 2012-12-10T18:58:24.190 回答
8

显然它不再是 with getDefaultOptions(),而是 with setDefaultOptions()

否则它说

选项“my_custom_option”不存在。已知选项有:“action”、“attr”、“auto_initialize”、...

所以,对我来说,我必须像这样更新 setDefaultOptions :

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array('my_custom_option' => false));
    // Others if needed, like in the documentation for : 'data_class' => 'VENDOR\Bundle\Entity\MyEntity', 'csrf_protection' => true
}

然后你可以在buildForm方法中检索它

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $myCustomOption = $options['my_custom_option'];
}
于 2013-11-26T10:31:38.257 回答
5

好吧,根据这个Google Groups

“greg0ire”是对的,事实上我已经尝试过并且效果很好!!!。你说“我真的不想去“破解”任何核心结构”但你最终没有使用最好的方法。事实上,从我的角度来看,你最终做了你没有做的事情想要做。

所以最后你应该这样做:

在表单类型

public function buildForm(FormBuilder $builder, array $options)
{
    $builder
        ->add('name')
        ->add('slug')
        ->add('reference')
        ->add('description')
        ->add('active_from')
        ->add('active_till')
        ->add('is_active')
        ->add('category', 'entity', array(
            'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory',
            'query_builder' => function(EntityRepository $er) {
                return $er->createQueryBuilder('u')
                    ->where('u.section = :id')
                    ->setParameter('id', $options['id'])
                    ->orderBy('u.root', 'ASC')
                    ->addOrderBy('u.lft', 'ASC');
            },
            'empty_value' => 'Choose an option',
            'property' => 'indentedName',
        ));
}

public function getDefaultOptions()
{
    return array(
        'data_class' => 'DEMO\DemoBundle\Entity\Product\Product'
        'id' => null
    );
}

并且在控制器中

$form = $this->createForm(new ProductType(), $product, array('id' => $id ));
于 2012-08-02T02:45:49.697 回答
1

通过表单类__construct方法传递选项,如下所示:

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;

class ProductType extends AbstractType
{

    private $options = array();
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('slug')
            ->add('reference')
            ->add('description')
            ->add('active_from')
            ->add('active_till')
            ->add('is_active')
            ->add('category', 'entity', array(
                'class' => 'DEMO\DemoBundle\Entity\Product\ProductCategory',
                'query_builder' => function(EntityRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->where('u.section = :id')
                        ->setParameter('id', $this->options['id'])
                        ->orderBy('u.root', 'ASC')
                        ->addOrderBy('u.lft', 'ASC');
                },
                'empty_value' => 'Choose an option',
                'property' => 'indentedName',
            ));
    }

    public function getDefaultOptions()
    {
        return array(
            'data_class' => 'DEMO\DemoBundle\Entity\Product\Product'
        );
    }

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

    public function __construct(array $options)
    {
        $this->options = $options;
    }
}

然后你可以这样做:

new ProductType(array('id'=>1));
于 2012-04-30T15:28:13.833 回答
1

好吧,事实证明,Gregoires 的答案非常接近,但是在尝试实际但将变量放入 createQueryBuilder 函数时却给了我和“未定义的变量”错误。

我花了一段时间试图找出原因并找到了问题所在。您必须在“query_builder”选项中为函数添加一个额外的参数,如下所示:

'query_builder' => function(EntityRepository $er) use ($options) {
                    return $er->createQueryBuilder('u')
                        ->where('u.section = :id')
                        ->setParameter('id', $options['id'])
                        ->orderBy('u.root', 'ASC')
                        ->addOrderBy('u.lft', 'ASC');
                },

神奇的设置是“使用($options)”。这允许您在查询构建器中成功使用 $options['id']。

于 2012-05-01T13:06:16.587 回答