Symfony 4表单嵌入集合allow_add不生效,无法获取新增项数据如何解决
问题1:表单元素不在<form>有效作用域内(最高概率)
你的Twig模板中标签嵌套顺序错误,浏览器会自动纠错闭合form标签,导致所有cropProductionEvents相关输入框(包括原有和新增)都在form之外,提交时自然不会被携带:
{# 你当前的错误结构 #} <div class="card card-body"> {{ form_start(form) }} {{ form_row(form.Crop_production) }} </div> {# 此处card-body关闭,浏览器会自动将未闭合的form标签也在此处闭合 #} {# 下面所有event相关的元素全部在form标签外 #} <div class="col-sm-12 col-sm-offset-2"> <legend>Crop production events</legend> <div id="event_list">...</div> </div> {{ form_end(form) }} {# 此处的form结束标签会被浏览器忽略 #}
修复方法:调整标签顺序,把所有表单元素都放在form_start和form_end内部:
{% block main %} {{ form_start(form) }} {# form标签放最外层 #} <div class="card card-body"> {{ form_row(form.Crop_production) }} </div> <div class="col-sm-12 col-sm-offset-2"> <legend class="col-form-label required mt-3">Crop production events</legend> <div class="row" id="event_list" data-prototype="{{ form_widget(form.cropProductionEvents.vars.prototype)|e }}"> {% for row in form.cropProductionEvents %} <div class="panel panel-warning"> <div class="col-md-12 col-xl-12"> <div class="card mb-3 mt-3 widget-content"> <div class="widget-content-outer"> {{ form_row(row) }} </div> </div> </div> </div> {% endfor %} </div> </div> {{ form_end(form) }} {# 后面的script标签保持不变 #}
问题2:实体缺少对应的add/remove方法(调整标签后仍映射失败时排查)
你在CropProductionType中给cropProductionEvents设置了by_reference => false,Symfony会自动调用实体的addCropProductionEvent和removeCropProductionEvent方法完成子项映射,需要确保你的CropProduction实体中有这两个public方法,示例:
// App/Entity/CropProduction.php public function addCropProductionEvent(CropProductionEvent $event): self { if (!$this->cropProductionEvents->contains($event)) { $this->cropProductionEvents[] = $event; $event->setCropProduction($this); // 关联父实体,级联保存需要 } return $this; } public function removeCropProductionEvent(CropProductionEvent $event): self { if ($this->cropProductionEvents->removeElement($event)) { if ($event->getCropProduction() === $this) { $event->setCropProduction(null); } } return $this; }
同时确保cropProductionEvents属性初始化了ArrayCollection,且关联配置开启了级联持久化:
// App/Entity/CropProduction.php use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; class CropProduction { // ...其他属性 /** * @ORM\OneToMany(targetEntity=CropProductionEvent::class, mappedBy="cropProduction", cascade={"persist", "remove"}) */ private $cropProductionEvents; public function __construct() { $this->cropProductionEvents = new ArrayCollection(); } // ...其他方法 }
验证方法
调整后先打开浏览器开发者工具的网络面板,提交表单后查看请求的FormData中是否存在cropProductionEvents[索引][字段名]格式的参数:
- 如果没有,继续检查表单元素是否在form标签内
- 如果有但是实体没有保存,检查add方法和实体级联配置
内容的提问来源于stack exchange,提问作者antonio
相关产品推荐
相关产品推荐

