Symfony2 在同一模板中覆盖 collection_widget 两次

Symfony2 override collection_widget twice in the same template

我有一个包含两个集合的联系人表单:功能和评论。 评论集合非常标准,不需要任何调整(只需文本字段和文件上传)。 但是函数需要覆盖 collection-item 因为我在选项卡中呈现每个函数。 我的问题是,当我为函数自定义 collection_item 小部件时,它还会尝试应用于评论集合的原型。它失败了,因为字段明显不同。

我如何通过强制评论集合使用标准 collection_item 小部件来管理它?或者可能通过将变量传递给 collection_widget 块,使其行为不同,具体取决于它是否适用于函数或注释...

--编辑:添加树枝模板--

这是我的主要编辑表单:

{% extends 'contactsBundle:templates:edit.html.twig' %}
{% form_theme edit_form 'contactsBundle:forms:fonctions.html.twig' %}

{% block form_body -%}

    <div class="row">
        <div class="col-md-5">
            {{ form_row(edit_form.prefix) }}
            {{ form_row(edit_form.nom) }}
            {{ form_row(edit_form.prenom) }}
        </div>
        <div class="col-md-5 col-md-offset-2">
            {{ form_row(edit_form.referent) }}
            {{ form_row(edit_form.groupe) }}
        </div>
    </div>
    {{ form_label(edit_form.fonctions) }}
    {{ form_errors(edit_form.fonctions, {attr: {class: 'fonctions-label'}}) }}
    {{ form_widget(edit_form.fonctions, {attr: {class: 'fonctions-widget'}}) }}
    <ul class="nav nav-tabs">
    </ul>
    <div class="tab-content">
        {% for fonction in edit_form.fonctions %}
            {% include 'contactsBundle:forms:fonctions-prototype.html.twig' with {form: fonction.vars.form, index: loop.index} %}
        {% endfor %}
    </div>
    <div class="row">
        <div id="commentaire_prototype">
            data-prototype="{{ form_widget(edit_form.commentaires.vars.prototype) | e }}"
        </div>
        {% for commentaire in edit_form.commentaires %}
            {{ form_row(commentaires.commentaire) }}
            {{ form_row(commentaires.docFile) }}
        {% endfor %}
    </div>

{% endblock form_body %}

{% block body_end_before_js %}
    {{ parent() }}
    <script src="{{ asset('bundles/mopabootstrap/js/mopabootstrap-collection.js') }}"></script>
    <script src="{{ asset('bundles/contacts/js/forms.js') }}"></script>
{% endblock body_end_before_js %}

这是我定制的collection_widget

{% extends 'contactsBundle:templates:edit.html.twig' %}
{% form_theme edit_form 'contactsBundle:forms:fonctions.html.twig' %}

    {% block form_body -%}

        <div class="row">
            <div class="col-md-5">
                {{ form_row(edit_form.prefix) }}
                {{ form_row(edit_form.nom) }}
                {{ form_row(edit_form.prenom) }}
            </div>
            <div class="col-md-5 col-md-offset-2">
                {{ form_row(edit_form.referent) }}
                {{ form_row(edit_form.groupe) }}
            </div>
        </div>
        {{ form_label(edit_form.fonctions) }}
        {{ form_errors(edit_form.fonctions, {attr: {class: 'fonctions-label'}}) }}
        {{ form_widget(edit_form.fonctions, {attr: {class: 'fonctions-widget'}}) }}
        <ul class="nav nav-tabs">
        </ul>
        <div class="tab-content">
            {% for fonction in edit_form.fonctions %}
                {% include 'contactsBundle:forms:fonctions-prototype.html.twig' with {form: fonction.vars.form, index: loop.index} %}
            {% endfor %}
        </div>
        <div class="row">
            <div id="commentaire_prototype">
                {#data-prototype="{{ form_widget(edit_form.commentaires.vars.prototype) | e }}"#}
            </div>
            {#{{ form_row(edit_form.commentaires) }}#}
            {% for commentaire in edit_form.commentaires %}
                {{ form_row(commentaires.commentaire) }}
                {{ form_row(commentaires.docFile) }}
            {% endfor %}
        </div>

    {% endblock form_body %}

{% block body_end_before_js %}
    {{ parent() }}
    <script src="{{ asset('bundles/mopabootstrap/js/mopabootstrap-collection.js') }}"></script>
    <script src="{{ asset('bundles/contacts/js/forms.js') }}"></script>
{% endblock body_end_before_js %}

这是我的 fonctions.prototype.html.twig:

{% if index is not defined %}
    {% set index = "__name__" %}
{% endif %}

<div class="collection-item tab-pane" id="{{ index }}">
    <div class="row">
        <div class="col-md-5">
            {{ form_row(form.fonction, {'attr': {'class': 'fonction'} } ) }}
            {{ form_row(form.titre) }}
            {{ form_row(form.entite, {'attr': {'class': 'entite'} }) }}
            {#Todo Add entity address#}
        </div>
        <div class="col-md-5 col-md-offset-2">
            {% if index is defined %}
                <div class="form-group">
                    <a class="btn btn-xs btn-danger coll-del" href="#">
                        <span class="glyphicon glyphicon-trash"></span>
                        Supprimer cette Fonction
                    </a>
                </div>
            {% else %}
                <div class="form-group">
                    <a class="btn btn-xs btn-danger coll-del"  data-collection-remove-btn=".curuba_contactsbundle_contacts_fonction___name___form_group" href="#">
                        <span class="glyphicon glyphicon-trash"></span>
                        Supprimer cette Fonction
                    </a>
                </div>
            {% endif %}
        </div>
    </div>

    <div class="row">
        <div class="col-md-5">
            <h4>Contact Professionel</h4>
            {{ form_row(form.persoFixe) }}
            {{ form_row(form.persoMobile) }}
            {{ form_row(form.persoFax) }}
            {{ form_row(form.persoMail) }}
        </div>
        <div class="col-md-5 col-md-offset-2">
            <h4>Secrétariat</h4>
            {{ form_row(form.assFixe) }}
            {{ form_row(form.assMobile) }}
            {{ form_row(form.assFax) }}
            {{ form_row(form.assMail) }}
        </div>
    </div>
</div>

来源:http://symfony.com/doc/current/cookbook/form/create_custom_field_type.html

我会继续这样说:

创建两种表单类型(Bundle\Form\Type\FunctionTypeBundle\Form\Type\CommentType

记下每个 getName() 的 return 值并将您的新表单类型注册为服务,对于以下我假设 curuba_commentcuruba_function:

#services.yml
services:
    bundle.form.type.function:
        class: Bundle\Form\Type\FunctionType
        tags:
            - { name: form.type, alias: curuba_function }
    bundle.form.type.comment:
        class: Bundle\Form\Type\CommentType
        tags:
            - { name: form.type, alias: curuba_comment }

现在,在您的表单主题中,您可以添加块 curuba_comment_widgetcurubu_function_widget可以调用其他块,例如collection_widget.

然后在您的表单中输入表单 ->add('somefield', 'comment')

以下是我如何以简单的方式管理它,这要归功于 post: symfony2 multiple nested forms prototype

首先我为每个集合更改 prototype_name :

$builder

            ->add('prefix')
            ->add('nom')
            ->add('prenom')
            ->add('referent')
            ->add('groupe')
            ->add('fonctions', 'collection', array(
                'type'          => new fonctionsType(),
                'allow_add'     => true,
                'allow_delete'  => true,
                'by_reference'  => false,
                'label'         => 'Fonctions',
                'label_attr' => array('class'=>'sub-form-label'),
                'prototype_name'=> '__fon_prot__'
            ))
            ->add('commentaires', 'collection', array(
                'type'          => new commentairesType(),
                'allow_add'     => true,
                'allow_delete'  => true,
                'by_reference'  => false,
                'label'         => 'Commentaires',
                'prototype'     => true,
                'prototype_name'=> '__com_prot__'
            ))
            ->add('submit', 'submit', array('label' => 'Enregistrer', 'attr' => array('class' => 'btn btn-lg btn-success')))

然后我在 collection_widget 中添加一个 if 语句:

{% if prototype.vars.name == '__fon_prot__' %}
    {% set prototype_markup = include('contactsBundle:forms:fonctions-prototype.html.twig', { 'form': form.vars.form.vars.prototype }) %}
{% else %}
    {% set prototype_markup = form_row(prototype) %}
{% endif %}

就是这样。