我的应用程序当前使用构造函数将数据传递给我的表单类型,如本答案中所建议的那样.但是,Symfony 2.8升级指南建议不要使用将类型实例传递给该createForm
函数:
将类型实例传递给Form :: add(),FormBuilder :: add()和FormFactory :: create*()方法已弃用,在Symfony 3.0中将不再受支持.传递类型的完全限定类名.
Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class);
由于我无法通过完全限定的类名传递数据,还有其他选择吗?
这打破了我们的一些形式.我通过选项解析器传递自定义数据来修复它.
在您的表单类型中:
public function buildForm(FormBuilderInterface $builder, array $options) { $this->traitChoices = $options['trait_choices']; $builder ->add('name', TextType::class, ['label' => 'L_PROFILE_EDIT_NAME', 'required' => false]) ... ->add('figure_type', ChoiceType::class, [ 'label' => 'L_PROFILE_EDIT_FIGURETYPE', 'mapped' => false, 'choices' => $this->traitChoices['figure_type'] ]) ... ; } /** * {@inheritdoc} */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Foo\BarBundle\Entity\Profile', 'trait_choices' => null, )); }
然后,当您在控制器中创建表单时,将其作为选项而不是在构造函数中传递:
$form = $this->createForm(ProfileEditType::class, $profile, array( 'action' => $this->generateUrl('profile_update'), 'method' => 'PUT', 'trait_choices' => $traitChoices, ));
这里可以使用另一种方法 - 为检索数据注入服务.
描述您的表格作为服务(食谱)
将受保护的字段和构造函数添加到表单类中
使用注入的对象获取所需的任何数据
例:
services: app.any.manager: class: AppBundle\Service\AnyManager form.my.type: class: AppBundle\Form\MyType arguments: ["@app.any.manager"] tags: [ name: form.type ]
manager = $manager; } public function buildForm(FormBuilderInterface $builder, array $options) { $choices = $this->manager->getSomeData(); $builder ->add('type', ChoiceType::class, [ 'choices' => $choices ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => 'AppBundle\Entity\MyData' ]); } }
如果有人在form.factory服务中使用'createNamedBuilder'或'createNamed'函数,那么这里有关于如何使用它设置和保存数据的代码片段.您不能使用'data'字段(保留null),您必须将传递的数据/实体设置为$options
值.
我还整合了@sarahg有关使用setAllowedTypes()和setRequired()选项的说明,它似乎工作正常,但您首先需要使用setDefined()定义字段
如果您需要设置数据,还要在表单内部记住将其添加到"数据"字段.
在Controller中我使用getBlockPrefix作为getName在2.8/3.0中被弃用
控制器:
/* * @var $builder Symfony\Component\Form\FormBuilderInterface */ $formTicket = $this->get('form.factory')->createNamed($tasksPerformedForm->getBlockPrefix(), TaskAddToTicket::class, null, array('ticket'=>$ticket) );
形成:
public function configureOptions(OptionsResolver $resolver) { $resolver->setDefined('ticket'); $resolver->setRequired('ticket'); $resolver->addAllowedTypes('ticket', Ticket::class); $resolver->setDefaults(array( 'translation_domain'=>'AcmeForm', 'validation_groups'=>array('validation_group_001'), 'tasks' => null, 'ticket' => null, )); } public function buildForm(FormBuilderInterface $builder, array $options) { $this->setTicket($options['ticket']); //This is required to set data inside the form! $options['data']['ticket']=$options['ticket']; $builder ->add('ticket', HiddenType::class, array( 'data_class'=>'acme\TicketBundle\Entity\Ticket', ) ) ... }
这是使用Symfony 3的任何人将数据传递到嵌入式表单的方法。首先完全执行上面概述的@sekl,然后执行以下操作:
在您的主要FormType中
使用' entry_options ' 将var传递给嵌入式表单
->add('your_embedded_field', CollectionType::class, array( 'entry_type' => YourEntityType::class, 'entry_options' => array( 'var' => $this->var )))
在您的嵌入式FormType中
将选项添加到optionsResolver
public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Yourbundle\Entity\YourEntity', 'var' => null )); }
访问buildForm函数中的变量。请记住在构建器函数之前设置此变量。就我而言,我需要根据特定的ID过滤选项。
public function buildForm(FormBuilderInterface $builder, array $options) { $this->var = $options['var']; $builder ->add('your_field', EntityType::class, array( 'class' => 'YourBundle:YourClass', 'query_builder' => function ($er) { return $er->createQueryBuilder('u') ->join('u.entity', 'up') ->where('up.id = :var') ->setParameter("var", $this->var); })) ; }