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实例。
修复步骤:
修正表单实例化逻辑
去掉?? 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); }给表单添加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>添加表单提交处理逻辑
引入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
相关产品推荐
相关产品推荐

