Symfony Twig嵌入表单:渲染的原型格式错误致提交报错
问题根源
核心问题是原型渲染内容与现有循环渲染内容不一致:
- 现有已填充字段是渲染
mailForm.mail(对应Mail实体的mail属性字段),因此name属性为member[mails][4][mail],结构是成员[邮件集合][索引][邮件属性]。 - 但你在原型中使用
form_row(memberForm.mails.vars.prototype),这是渲染整个EmailType表单的原型,而EmailType本身包含mail字段,导致生成的name属性为member[mails][5],缺少[mail]层级,提交时无法正确映射到Mail实体的属性。
解决方案
修改Twig模板的原型渲染逻辑,让原型和现有循环渲染的内容保持一致:
1. 修正Twig模板的原型部分
将原模板中的:
data-prototype="{{ form_row(memberForm.mails.vars.prototype)|e('html_attr') }}"
替换为:
data-prototype="{{ form_row(memberForm.mails.vars.prototype.mail)|e('html_attr') }}"
这样原型会直接渲染EmailType中的mail子字段,和现有循环里的form_row(mailForm.mail)结构完全匹配。
2. 验证JavaScript逻辑
你的JS替换__name__占位符的逻辑是正确的,修改原型后,新生成字段的name属性会自动变为member[mails][5][mail],和现有字段结构一致。
额外优化(可选)
如果希望现有字段和新生成字段的input类型统一(现有是text,新生成是email),可以在EmailType中明确指定字段类型:
// EmailType的buildForm方法内 $builder->add('mail', TextType::class, [ 'maxlength' => 30, ]);
或者保持EmailType默认的email类型,确保现有字段的渲染配置和原型一致。
修改后效果验证
调整后,新生成的input字段结构会和现有字段完全一致:
<input type="text" id="member_mails_5_mail" name="member[mails][5][mail]" maxlength="30" class="form-control">
此时提交表单可正确映射到Mail实体,不会再出现无效报错。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

