因此,我的自定义表单类型中的CollectionType出现问题。当我向集合中添加两个新表单并正确填写它们并提交时,只有最后一个选项被提交。过去四个小时我一直在绞尽脑汁试图解决这个问题。
class CustomType extends AbstractType
{
public function buildForm(...)
{
$builder->add(
'collection',
CollectionType::class,
[
'required' => false,
'entry_type' => CustomItemType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'label' => 'Some label',
'by_reference' => false,
'error_bubbling' => false,
'entry_options' => [
'empty_data' => new CustomItem(),
'by_reference' => false
]
]
);
}
public function configureOptions(...)
{
$resolver->setDefaults(['data_class' => CustomContainer::class]);
}
}
如果您需要更多信息,请询问我,我将提供。我已经使用jQuery和CollectionType类提供的原型实现了子表单的添加。我在www.example.com上学习了教程symfony.com,现在我不知道该往哪个方向走。任何帮助都是非常感谢的。
我确实对表单做了一些调试,数据被正确提交,但是当它对表单对象进行水合时,它会为添加的每个条目传递表单中的最后一项。
编辑
function addItem(e) {
e.preventDefault();
var collectionSelector = $(this).data('collection-selector');
var list = $(collectionSelector);
var counter = list.data('widget-counter');
var newWidget = list.data('prototype');
var newHtmlElem = newWidget.replace(/__name__/g, counter);
var newElem = $(newHtmlElem);
newElem.on('click', e.data.removeButtonClass, {itemContainerClass: e.data.itemContainerClass}, removeItem);
counter++;
list.data('widget-counter', counter);
var accordianContainer = $(collectionSelector + ' ' + e.data.collapse);
newElem.appendTo(accordianContainer);
}
$(document).ready(function () {
$('body').tooltip({selector: '.custom-tooltip'});
$('.add-custom-item-btn').click({removeButtonClass: '.remove-custom-item-btn', itemContainerClass: '.custom-item-item', collapse: '#custom-item-accordion'}, addItem);
$('.remove-custom-item-btn').click({itemContainerClass: '.custom-item-item'}, removeItem);
});
这是tweg模板的一个片段
{% macro printItem(custom_item, index) %}
<div class="panel panel-default custom-item-item">
<div class="panel-heading" role="tab" id="custom-item-heading-{{ index }}>
<h4 class="panel-title">
<a role="button"
data-toggle="collapse"
data-parent="#custom-item-accordion"
href="#custom-item-collapse-{{ index }}"
class="collapsed"
>
Custom Item
</a>
</h4>
</div>
<div id="custom-item-collapse-{{ index }}"
class="panel-collapse collapse"
role="tabpanel"
aria-labelledby="custom-item-heading-{{ index }}"
aria-expanded="false"
>
<div class="panel-body">
{{ form_row(custom_item) }}
<button type="button" class="remove-custom-item-btn btn btn-primary btn-sm">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
</button>
</div>
</div>
</div>
{% endmacro %}
{% import _self as formMacros %}
<div class="row">
<div class="col-xs-12 form-group">
<button type="button" class="add-custom-item-btn btn btn-primary btn-sm" data-collection-selector="#custom-container-fields-list">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</div>
<div id="custom-container-fields-list"
data-prototype="{{ formMacros.printItem(form.collection.vars.prototype, '__name__') }}"
data-widget-counter="{{ max(form.collection|keys) + 1 }}"
>
<div class="panel-group" id="custom-item-accordion" role="tablist" aria-multiselectable="true">
{% for index, custom_item in form.collection %}
{{ formMacros.printItem(custom_item, index) }}
{% endfor %}
</div>
</div>
</div>
***编辑***我已经创建了一个repo,它演示了所有类的这个问题,这样您就可以随时查看它。不,这不是实际的代码,但问题仍然存在。我使用的是PHP 8.1和symfony 5.4,但所有这些都可以在下面的repo中的composer.json文件中看到。如果有人能提供一些信息,我将非常感激。或者,如果大家一致认为这是一个bug,我会用symfony记录一个bug,但我宁愿先确定这一点。
1条答案
按热度按时间k4ymrczo1#
您的问题似乎是由
CustomType
中的这一行引起的:由于您已经将
empty_data
设置为CustomItem
的单个示例,因此每个新行都将重用此相同的示例。在
CollectionType
上,您还将by_reference
设置为false,这意味着CustomContainer
类上的adder方法将使用相同的CustomItem
示例为每个新行调用。假设您已经使用了make:entity
命令,则该adder方法仅在CustomItem
对象的数组中不存在相同的示例时才添加该对象,这就解释了缺少项的原因。解决方案是为每个新行创建一个新的
CustomItem
示例,如下面的示例所示:https://webmozart.io/blog/2015/09/09/value-objects-in-symfony-forms/(在The empty_data Option
下)