php Symfony2 - 如何在使用表单类时设置和获取选项?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10382075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:03:58  来源:igfitidea点击:

Symfony2 - How to set, and get, options when using a Form Class?

phpsymfony

提问by Mr Pablo

I am using Form Classes to build the various form in my project.

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

In the Entity Type file, for the buildForm function, there is a secondary parameter of "array $options" (this is shown in the official Symfony 2 Documentation, but never mentioned, ever!)

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

I have fed an array into the createForm function in my controller but now I am totally stumped on how to retrieve the stored values?

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

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

The only thing I have found about getting the options is using the getOption() function, but that doesn't exist in Symfony 2 (the post I found was from 2010).

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

I tried using:

我尝试使用:

$id = $options['id'];

But when I try to use $id anywhere, I get the error:

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

Notice: Undefined index: id

注意:未定义索引:id

What gives?

是什么赋予了?

How do I retrieve my values from the $options array? Am I even setting them correctly in the first place?

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

EDIT - More code:

编辑 - 更多代码:

Form Class

表单类

<?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';
    }
}

采纳答案by Mr Pablo

Well, it turns out, Gregtheitroades answer was very close, but gave me and "Undefined variable" error when trying to actually but the variable into the createQueryBuilder function.

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

I spent a while trying to figure out why and found the issue. You have to add an extra parameter to the function in the "query_builder" option, like such:

我花了一段时间试图找出原因并找到了问题所在。您必须在“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');
                },

The magic setting being "use ($options)". This allows you to successfully use $options['id'] in the Query Builder.

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

回答by greg0ire

I think you're not setting them properly in the first place. You're supposed to give them as third argument to createForm()

我认为你一开始就没有正确设置它们。你应该给他们作为第三个论点createForm()

EDIT: Here is how your form class could look:

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

<?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';
    }
}

回答by Iulian M

Let me show you what worked for me

让我告诉你什么对我有用

In the Controller:

在控制器中:

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

In the FormType:

在 FormType 中:

->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
},
));

回答by Bonswouar

Apparently it's not with getDefaultOptions()anymore, but with setDefaultOptions().

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

Otherwise it says

否则它说

The option "my_custom_option" does not exist. Known options are: "action", "attr", "auto_initialize", ...

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

So, for me I had to update setDefaultOptions like this :

所以,对我来说,我必须像这样更新 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
}

And then you can retrieve it in the buildFormmethod

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

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $myCustomOption = $options['my_custom_option'];
}

回答by Richard Pérez

Well acording to this Google Groups

好吧,根据这个Google Groups

"greg0ire" was right, in fact I have tried it and works perfect!!!. You said "I dont really want to go about "hacking" any of the core structure" but you end up using no the best approach.. in matter of fact, from my point of view, you end up doing what you didn't want to do.

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

So at the end you should do this:

所以最后你应该这样做:

at the formType

在表单类型

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
    );
}

And in the controller

并在控制器中

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

回答by Flukey

Pass the options through the forms class __constructmethod, like so:

通过表单类__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;
    }
}

And then you can do:

然后你可以这样做:

new ProductType(array('id'=>1));