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

Symfony UX Live Components编辑表单报错:期望string,传入null

问题描述

使用Symfony UX Live Components编辑NtExam对象时,提交表单触发以下错误:

Expected argument of type "string", "null" given at property path "exam_title"

已确认NtExam对象的exam_title字段存在有效值,但表单提交时传入null导致错误。相关代码如下:

Component代码

#[AsLiveComponent]
class ExamEditComponent
{
    #[LiveProp(writable: true)]
    public ?NtExam $ntExam = null;

    public bool $showForm = false;

    public function __construct(private NtExamRepository $ntExamRepository) {}

    public function instantiateForm(): FormInterface
    {
        $exam = $this->ntExam ?? new NtExam();
        return $this->createForm(NtExamType::class, $exam);
    }

    #[LiveAction]
    public function editExam(#[LiveArg] int $id)
    {
        $this->ntExam = $this->ntExamRepository->find($id);
        $this->showForm = true;
    }
}

编辑按钮代码

<button class="nt-btn-grey" data-action="live#action" data-live-action-param="editExam"
    data-live-id-param="{{ nt_exam.id }}">{{ ux_icon('lucide:file-pen-line',{height :
    '16px'}) }}
    <span>Edit</span></button>

表单类型(NtExamType)代码

class NtExamType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->add('exam_title', TextType::class);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults(['data_class' => NtExam::class]);
    }
}

Twig模板代码

<div>
    {% if component.showForm %}
        {{ form_start(form) }}
        {{ form_row(form.exam_title) }}
        {{ form_end(form) }}
    {% endif %}
</div>

解决方案

这个问题核心是表单提交时未正确绑定到已加载的ntExam对象,导致组件状态丢失,表单重新绑定到空的NtExam实例。

修复步骤:

  1. 修正表单实例化逻辑
    去掉?? new NtExam()的兜底逻辑,因为只有点击编辑按钮才会显示表单,此时ntExam必然已被赋值,直接绑定到该属性:

    public function instantiateForm(): FormInterface
    {
        if (!$this->ntExam) {
            throw new \LogicException('ntExam must be set to instantiate the form.');
        }
        return $this->createForm(NtExamType::class, $this->ntExam);
    }
    
  2. 给表单添加Live Component提交动作
    表单必须通过live#submit提交,否则会触发整页刷新,丢失组件状态。修改Twig模板:

    <div>
        {% if component.showForm %}
            {{ form_start(form, {'attr': {'data-action': 'live#submit'}}) }}
            {{ form_row(form.exam_title) }}
            <button type="submit">保存</button>
            {{ form_end(form) }}
        {% endif %}
    </div>
    
  3. 添加表单提交处理逻辑
    引入DefaultActionTrait处理默认提交,同时添加持久化逻辑:

    use Symfony\UX\LiveComponent\DefaultActionTrait;
    use Doctrine\ORM\EntityManagerInterface;
    
    #[AsLiveComponent]
    class ExamEditComponent
    {
        use DefaultActionTrait;
    
        #[LiveProp(writable: true)]
        public ?NtExam $ntExam = null;
    
        public bool $showForm = false;
    
        public function __construct(
            private NtExamRepository $ntExamRepository,
            private EntityManagerInterface $em
        ) {}
    
        public function instantiateForm(): FormInterface
        {
            if (!$this->ntExam) {
                throw new \LogicException('ntExam must be set to instantiate the form.');
            }
            return $this->createForm(NtExamType::class, $this->ntExam);
        }
    
        #[LiveAction]
        public function editExam(#[LiveArg] int $id)
        {
            $this->ntExam = $this->ntExamRepository->find($id);
            $this->showForm = true;
        }
    
        public function submitForm(): void
        {
            $this->em->persist($this->ntExam);
            $this->em->flush();
            $this->showForm = false;
        }
    }
    

关键原因说明:

  • 原表单未使用live#submit,提交时绕过Live Component状态管理,导致组件重新初始化,ntExam变回null。
  • instantiateForm中的兜底逻辑会创建空的NtExam实例,提交时自然没有原有值,触发字段非空校验错误。

内容的提问来源于stack exchange,提问作者Demi God

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 09:23:13