我正在尝试按照Symfony 2.7文档使用Embed a Collection of Forms创建custom Collection Prototype。
问题是,我无法按照文档中的说明创建自定义集合原型。
如示例中所示,有两个简单的类:
一个Task
类,用于管理任务的描述以及任意数量的标记,由其自己的Tag
类
class Task {
protected $description;
protected $tags;
public function __construct() {
$this->tags = new array();
}
// Getter & Setter for description + additional addTag & removeTag methods
// ...
// Tags getter
public function getTags() {
return $this->tags;
}
}
class Tag {
protected $name;
// ... setName(...), getName()...
}
这些是自定义表单类型:
class TaskType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('description');
$builder->add('tags', 'collection', array('type' => new TagType()));
}
public function getName() {
return 'task';
}
// ...
}
class TagType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('name');
}
public function getName() {
return 'tag';
}
// ...
}
呈现表单的Twig文件
{{ form_start(form) }}
{# render the task's only field: description #}
{{ form_row(form.description) }}
{# render tags - use table instead of ul as in example #}
<div class="table-responsive">
<table class="table">
<thead>
<th>{{ 'task.tag.headline'|trans }}</th>
</thead>
<tbody class="tags-container" data-prototype="{{ form_widget(form.tags.vars.prototype)|e('html_attr') }}">
{{ form_row(form.rules) }}
</tbody>
</table>
</div>
{{ form_end(form) }}
这很好,并在表格中呈现tags
列表。 但是,此代码使用默认原型,(当然)不会为不同的标记创建表行。
我尝试添加代码以使用自定义原型作为described in the docs。然而,文档没有说明添加此代码的位置或如何使用它:
使用自定义原型代码的Twig代码
{{ form_start(form) }}
{# Custom Prototype Code from docs #}
{% form_theme form _self %}
{% block _tags_entry_widget %}
<tr>
<td>{{ form_widget(form.name) }}</td>
</tr>
{% endblock %}
{# render the task's only field: description #}
{{ form_row(form.description) }}
{# render tags - use table instead of ul as in example #}
<div class="table-responsive">
<table class="table">
<thead>
<th>{{ 'task.tag.headline'|trans }}</th>
</thead>
<tbody class="tags-container" data-prototype="{{ form_widget(form.tags.vars.prototype)|e('html_attr') }}">
{{ form_row(form.rules) }}
</tbody>
</table>
</div>
{{ form_end(form) }}
使用这样的自定义原型代码会导致错误:
方法&#34;名称&#34; for object&#34; Symfony \ Component \ Form \ FormView&#34;不 不存在于&#34; MyAppBundle:任务:task.html.twig&#34;
这听起来很合理,因为name
属于Tag
类,而不属于Task
类。
问题1:如何在模板中使用/访问Tag
表单?**
我从原型模板中删除了<td>{{ form_widget(form.name) }}</td>
,并将其替换为<td>Test</td>
以查看是否使用了该模板。结果:模板未使用且无效。
问题2:设置/激活原型模板的正确方法是什么?
我发现其他线程处理原型问题/问题。答案提出了使用宏,外部twig文件等的不同解决方案。由于Symfony文档似乎在不使用宏等黑客的情况下在同一文件中提供解决方案,我想知道实现此解决方案。 < / p>
答案 0 :(得分:3)
这对我有用 - 对不起 - 这是Symfony 3,但你应该能够翻译。
在PersonType类的buildForm方法中,我的CollectionType为电子邮件
->add( 'emails', CollectionType::class, [
'label' => 'common.email',
'entry_type' => AppEmailType::class,
'by_reference' => true,
'required' => false,
'label' => false,
'empty_data' => null,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'mapped' => false,
'prototype_name' => '__email__'
] )
呈现PersonType的模板包括类似的电子邮件
{% include 'common/emails.html.twig' with {'form': form.emails } %}
<强>公共/ emails.html.twig 强>
此模板是集合的容器
<div class="emails">
<span class="sub-form-legend">{{'common.email'|trans}}</span>
{{form_row(form)}}
{% if form.vars.allow_add %}
<div class="add-one-more-row">{{ 'common.add_one_more'|trans}}</div>
{% endif %}
</div>
在 fields.html.twig 中,我有一个特定于表单的entry_row模板,该模板使用在同一文件中定义的通用电子邮件模板。
{% block _user_person_emails_entry_row %}
{{ block('_emails_entry_row') }}
{% endblock %}
{% block _emails_entry_row %}
{% spaceless %}
<div class="form-row email">
<span class="type-select">{{ form_widget(form.type) }}</span>
<span class="input">{{ form_widget(form.email) }}</span>
<span class="comment">{{ form_widget(form.comment) }}</span>
<span class="remove-form-row" title="{{'common.remove'|trans}}" id="email-__email__"><i class="fa fa-remove"></i></span>
</div>
{% endspaceless %}
{% endblock %}
要查找名称,请跟踪表单的名称,并在下面添加下划线。使用 {{dump(form)}} 获取唯一名称。
HTML将放在 data-prototype 属性中。