Symfony 4.4 如何实现CollectionType表单初始状态不生成任何字段
解决方案
1. 修改CollectionType配置
你遇到的空条目问题核心是Symfony的CollectionType默认initial_count参数值为1,这个参数控制无初始数据时默认生成的空条目数量,直接修改配置把它设为0即可:
// Builder ... ->add('contracts', CollectionType::class, [ 'entry_type' => ContractsType::class, 'entry_options' => ['label' => false], 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false, 'initial_count' => 0, // 新增这一行 ])
如果使用的Symfony版本低于4.3没有initial_count参数,可以补充empty_data配置:
'empty_data' => [],
2. 确认实体初始化配置
绑定的实体类中,$contracts属性要在构造函数中初始化为空集合,不要设置默认值:
// 实体类代码 use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; // ... private ?Collection $contracts = null; public function __construct() { $this->contracts = new ArrayCollection(); }
3. 调整Twig模板逻辑
现在初始状态下集合没有任何子条目,你可以直接简化模板,只保留外层带prototype数据的div即可,不需要多余的空判断:
{# Startdate, enddate and contract hours fields. Data sets are specific for each field since I need nice styling. #} <div id="ContractFields" class="contracts" data-start-label="{{ form_label(userEntityForm.contracts.vars.prototype.start_date, 'Begintijd')|e('html_attr') }}" data-start-date-year="{{ form_widget(userEntityForm.contracts.vars.prototype.start_date.year, { attr: { class: 'select-field mr-1' }})|e('html_attr') }}" data-start-date-week="{{ form_widget(userEntityForm.contracts.vars.prototype.start_date.week, { attr: { class: 'select-field' }})|e('html_attr') }}" data-end-label="{{ form_label(userEntityForm.contracts.vars.prototype.end_date, 'Eindtijd')|e('html_attr') }}" data-end-date-year="{{ form_widget(userEntityForm.contracts.vars.prototype.end_date.year, { attr: { class: 'select-field mr-1' }})|e('html_attr') }}" data-end-date-week="{{ form_widget(userEntityForm.contracts.vars.prototype.end_date.week, { attr: { class: 'select-field' }})|e('html_attr') }}" data-hours-label="{{ form_label(userEntityForm.contracts.vars.prototype.contract_hours, 'Contract uren')|e('html_attr') }}" data-hours="{{ form_widget(userEntityForm.contracts.vars.prototype.contract_hours, {'type' : 'number'})|e('html_attr') }}" data-index="0"> <!-- 初始化JS需要用到的index参数 --> </div>
如果有编辑已有数据的场景,可以补充已有数据的渲染逻辑:
<div id="ContractFields" class="contracts" {# 原有data属性配置不变 #} {% set dataLength = userEntityForm.contracts.vars.data|length %} data-index="{{ dataLength }}"> {% if dataLength > 0 %} {% for contract in userEntityForm.contracts %} {# 你原有循环渲染每个合同字段的逻辑 #} {% endfor %} {% endif %} </div>
4. 效果验证
改完后页面初始加载时,#ContractFields容器内不会生成任何集合子字段的HTML内容,只有你配置的自定义属性,完全符合点击「下一步」前不输出集合字段的要求,你的JS动态生成逻辑也不会被默认空条目干扰。
内容的提问来源于stack exchange,提问作者Allart
相关产品推荐
相关产品推荐

