将数据传递给Symfony 2.8 / 3.0中的buildForm()

我的应用程序当前使用构造函数将数据传递给我的表单types,如本答案中的build议。 但是, Symfony 2.8升级指南build议不build议将types实例传递给createForm函数:

将types实例传递给Form :: add(),FormBuilder :: add()和FormFactory :: create *()方法已被弃用,并且在Symfony 3.0中不再被支持。 改为传递types的完全限定类名称。

 Before: $form = $this->createForm(new MyType()); After: $form = $this->createForm(MyType::class); 

鉴于我无法通过完全合格的类名传递数据,是否有其他select?

这也打破了我们的一些forms。 我通过传递自定义数据通过选项parsing器来解决它。

在你的表单中input:

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

然后,当你在你的控制器中创build表单时,将它作为选项而不是在构造函数中传递:

 $form = $this->createForm(ProfileEditType::class, $profile, array( 'action' => $this->generateUrl('profile_update'), 'method' => 'PUT', 'trait_choices' => $traitChoices, )); 

如果有人正在使用form.factory服务中的“createNamedBuilder”或“createNamed”函数,请参阅如何使用它设置和保存数据的片段。 您不能使用“数据”字段(保留null),您必须将传递的数据/实体设置为$options值。

我还引入了关于使用setAllowedTypes()和setRequired()选项的@sarahg指令,它似乎工作正常,但是您首先需要使用setDefined()

如果您需要设置数据,也可以在表单里面记住将其添加到“数据”字段。

在控制器中我使用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的任何人的embedded式表单。首先执行上面概述的@sekl,然后执行以下操作:

在您的主要FormType中

使用“ entry_options ”将var传递给embedded的表单

 ->add('your_embedded_field', CollectionType::class, array( 'entry_type' => YourEntityType::class, 'entry_options' => array( 'var' => $this->var ))) 

在你的embedded式FormType中

将选项添加到optionsResolver

 public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Yourbundle\Entity\YourEntity', 'var' => null )); } 

访问您的buildForm函数中的variables。 请记住在构build器函数之前设置此variables。 就我而言,我需要根据特定的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); })) ; } 

这里可以使用另一种方法 – 注入服务来检索数据。

  1. 将你的表格描述为服务( 食谱 )
  2. 添加受保护的字段和构造函数以形成类
  3. 使用注入的对象来获取您需要的任何数据

例:

 services: app.any.manager: class: AppBundle\Service\AnyManager form.my.type: class: AppBundle\Form\MyType arguments: ["@app.any.manager"] tags: [ name: form.type ] 

 <?php namespace AppBundle\Form; use AppBundle\Service\AnyManager; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class MyType extends AbstractType { /** * @var AnyManager */ protected $manager; /** * MyType constructor. * @param AnyManager $manager */ public function __construct(AnyManager $manager) { $this->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' ]); } }