所以,进入排除这个问题的第5天仍然无法解决问题.我甚至创建了一个特殊的表格,只是为了解决这个问题,仍然没有取得任何进展.基本问题:我有一个通过FormBuilderInterface使用表单修饰符构建的Symfony2表单,根据用户对表单中第一个实体的选择动态填充字段.表单中还有3个集合(表示与表单主类的一对一关联).
无论我做什么,在if($form-> isValid())上我得到的是非常熟悉和有趣的“错误:这个表单不应该包含额外的字段.”表单提交错误(3次,每个集合1次).
值得注意并且可能与修复有关:如果我从表单中删除集合实体,它会正确验证.对于表单中的任何集合,或3个集合中的2个的任意组合(我已经尝试了所有),它会抛出“此表单不应包含额外字段”错误.
以下是表单类型的代码:
class ThisDataClassType extends AbstractType { protected $user_id; public function __construct($user_id) { $this->user_id = $user_id; } /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder,array $options) { $user_id = $this->user_id; $builder->add('firstChoice','entity',array( 'class' => 'MyBundle:FirstChoice','query_builder' => function(firstChoiceRepository $repository) use ($user_id) { return $repository->createQueryBuilder('f') ->where('f.user = ?1') ->andWhere('f.isActive = 1') ->setParameter(1,$user_id); },'property' => 'firstChoice_name','required' => true,'mapped' => false,'label' => 'block.firstChoice.name' )) ->add('sub_block_name','text',array( 'label' => 'subblock.block.name','max_length' => 50,'attr' => array( 'placeholder' => 'subblock.phv.name','pattern' => 'alpha_numeric' ) )) // ... bunch of other standard form types (text,etc.) ... // ->add('subdata1','collection',array( 'type' => new SubData1Type() )) ->add('subdata2',array( 'type' => new SubData2Type() )) ->add('subdata3',array( 'type' => new SubData3Type() )); $formModifier = function(FormInterface $form,$firstChoice_id) { $form->add('secondChoice',array( 'class' => 'MyBundle:SecondChoice','query_builder' => function(secondChoiceRepository $S_repository) use ($firstChoice_id) { return $S_repository->createQueryBuilder('s') ->where('s.firstChoice_id = ?1') ->andWhere('s.isActive = 1') ->setParameter(1,$firstChoice_id); },'property' => 'secondChoice_name','label' => 'block.secondChoice.name' )); }; $builder->addEventListener( FormEvents::PRE_SET_DATA,function(FormEvent $event) use ($formModifier) { $data = $event->getData()->getId(); $formModifier($event->getForm(),$data); } ); $builder->get('firstChoice')->addEventListener( FormEvents::POST_SUBMIT,function(FormEvent $event) use ($formModifier) { $data = $event->getForm()->getData(); $formModifier($event->getForm()->getParent(),$data->getId()); } ); $builder->setMethod('POST'); } /** * @param OptionsResolverInterface $resolver */ public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'MyBundle\Entity\ThisDataClass','user_id' => null,'translation_domain' => 'block','cascade_validation' => true )); } /** * @return string */ public function getName() { return 'ThisDataForm'; } }
…和基本控制器(此刻仅用于测试):
public function TestFormAction(Request $request,$whichSize) { $user_id = $this->getUser()->getId(); $success = 'Not submitted'; $dataclass = new Entity\ThisDataClass(); $subdata1 = new Entity\SubData1(); $subdata2 = new Entity\SubData2(); $subdata3 = new Entity\SubData3(); if (!$request->isMethod('POST')) { $dataclass->getSubData1()->add($subdata1); $dataclass->getSubData2()->add($subdata2); $dataclass->getSubData3()->add($subdata3); } $form = $this->createForm(new Form\ThisDataClassType($user_id),$dataclass,array( 'action' => $this->generateUrl('my_custom_test_route',array('whichSize' => $whichSize)),'user_id' => $user_id )); $form->handleRequest($request); if ($form->isValid()) { $success = 'Success!!'; return $this->render('MyBundle:DataClassTestForm.html.twig',array('dataClassTestForm' => $form->createView(),'whichSize' => $whichSize,'success' => $success)); } else { $success = $form->getErrorsAsString(); } return $this->render('MyBundle:DataClassTestForm.html.twig','success' => $success)); }
提一下其他几点:
>表单正确显示(所有实体显示正确的值并根据需要更新)
>所有预期的POST变量都在帖子数据中(通过Firebug和Symfony的Profiler检查)
>后期数据中没有额外的变量未映射到
类(具有’mapped’=> false set的firstChoice字段除外)
CSRF _token,但是我明确启用CSRF _token时会收到错误
或不,当我删除集合时,错误消失了)
非常感谢任何人对我缺少的东西的见解.
解决方法
在休息了一天半之后,当我坐下来时,答案突然显现.所写的控制器仅在首次创建时将子数据类添加到表单中(即,当没有发生提交/ POST事件时).因此,在提交事件之后创建的表单包含所有发布数据,但类与之无关.控制器现在已经被重写如下,表单现在按预期验证:
public function TestFormAction(Request $request,$whichSize) { $user_id = $this->getUser()->getId(); $success = 'Not submitted'; $dataclass = new Entity\ThisDataClass(); $subdata1 = new Entity\SubData1(); $subdata2 = new Entity\SubData2(); $subdata3 = new Entity\SubData3(); $dataclass->getSubData1()->add($subdata1); $dataclass->getSubData2()->add($subdata2); $dataclass->getSubData3()->add($subdata3); $form = $this->createForm(new Form\ThisDataClassType($user_id),'user_id' => $user_id )); $form->handleRequest($request); if ($form->isValid()) { $success = 'Success!!'; } else { $success = 'Invalid!!'; } } // RESULT::Success!!