Symfony 4中PRE_SET_DATA监听器setData无法更新自定义类型字段
问题:Symfony表单中未映射子表单的ChoiceType字段无法通过PRE_SET_DATA事件设置默认值
我有一个父表单类型,其中包含一个未映射的子表单类型。子表单包含三个ChoiceType字段,因特定格式要求需手动填充。字段加载正常,ChoiceType字段的数据保存也没问题,但子表单的ChoiceType字段需要用父表单的数据填充——我尝试在父表单的PRE_SET_DATA事件监听器中手动设置这些字段的默认值,监听器已被调用,也通过setData更新了字段,但表单加载后ChoiceType字段仍为空。
我测试过在ChoiceType字段内手动设置data属性为监听器中设置的相同值,此方法可行,所以问题肯定出在setData调用上。
示例代码如下:
class ParentType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('child_field', ChildType::class, [ 'required' => false, 'mapped' => false, 'label' => false ]) ->add('save', SubmitType::class, [ 'attr' => [ 'class' => 'save', ], ]) ->addEventSubscriber(new FormLoadedListener()); } ... }
class ChildType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('first_field', ChoiceType::class, [ 'required' => false, 'label' => 'First Field', 'choices' => $this->buildFirstChoices(), ]) ->add('second_field', ChoiceType::class, [ 'required' => false, 'label' => 'Second Field', 'choices' => $this->buildSecondChoices(), ]) ->add('third_field', ChoiceType::class, [ 'required' => false, 'label' => 'Third Field', 'choices' => $this->buildThirdChoices(), ]); } }
class FormLoadedListener implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ FormEvents::PRE_SET_DATA => 'onPreSetData' ]; } public function onPreSetData(FormEvent $event): void { $data = $event->getData(); $form = $event->getForm(); $firstValue = $this->doStuffToGetFirstValue(); $secondValue = $this->doStuffToGetSecondValue(); $thirdValue = $this->doStuffToGetThirdValue(); $childField = $form->get('child_field'); $childField->get('first_field')->setData($firstValue); $childField->get('second_field')->setData($secondValue); $childField->get('third_field')->setData($thirdValue); } }
我还尝试了其他设置数据的方法:
$form->get('child_field')->setData([ 'first_field' => $firstValue, 'second_field' => $secondValue, 'third_field' => $thirdValue ]);
以及:
$form->setData(['child_field' => [ 'first_field' => $firstValue, 'second_field' => $secondValue, 'third_field' => $thirdValue ]);
内容的提问来源于stack exchange,提问作者Adam Roberts
相关产品推荐
相关产品推荐

