You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:20:17