прототип нескольких вложенных форм symfony2

Я хочу включить тип коллекции в другую коллекцию. Это должно выглядеть так: enter image description here

использование только одной коллекции отлично работает, но мне нужно отредактировать прототип внешней формы, поэтому он отображает прототип внутренней формы для каждой строки.

любые идеи, как я могу это сделать? Также, что было бы лучшим способом сохранить

изменить: Теперь я пытаюсь отобразить прототип вложенной формы:

  <ul class="characteristics-container" data-prototype="{{ form_widget(form.characteristics.vars.prototype)|e }}" data-prototype-options="{{ form_widget(form.characteristics.options.vars.prototype|e ) }}">
                    {# iterate over each existing tag and render its only field: name #}
                    {% for characteristic in form.characteristics %}
                        <li>{{ form_row(characteristic.name) }}</li>

                        <div class="characteristics-options">
                            {% for opt in form.characteristics.options %}

                            {% endfor %}                     
                        </div>


                    {% endfor %}
                </ul>

это дает ошибку в form_widget(form.characteristics.options.vars.prototype|e

Method "options" for object "SymfonyComponentFormFormView" does not exist in 

Я пробовал характеристики[0], и он говорит, что ключ не существует

вот мои классы:

PromotionType (базовая форма)

$builder              
            ->add('characteristics','collection', array(
                'label'         => 'Caracteristicas',
                 'type'         => new PromotionCharacteristicType(),
                 'allow_add'    => true,
                 'allow_delete' => true,
                 'by_reference' => false
            ))

PromotionCharacteristicType

 $builder
            ->add('name',NULL, array('label'  => 'Nome'))
            ->add('options', 'collection', array(
                'type' => new PromotionCharacteristicOptionType(),
                'allow_add' => true,
                'allow_delete' => true,      
                'prototype' => true,
                'by_reference' => false,
            ))                       
        ;

PromotionCharacteristicOptionType

 $builder
            ->add('name',NULL, array('label'  => 'Nome')) 
        ;

прототип первого уровня, работает нормально.

2 ответов


формы и прототипа

вам нужно сохранить два прототипа из разных коллекций. Symfony предлагает хранить их в атрибуте data-prototype тега div, который обертывает коллекцию. В вашей ситуации это очень неэффективно. Таким образом, вы можете просто сделать это вручную в пустом div somethere

пример у вас есть символы, форма

class CharacterType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('opts', 'collection', array(
            'type' => new OptionType(),
            'allow_add' => true,
            'allow_delete' => true,
            'prototype' => true,
            'prototype_name' => '__opt_prot__'
        ));
        $builder->add('char_desc', 'text');
    }

    public function getName()
    {
        return 'char';
    }
}

затем создать форму, которая имеет коллекцию символов

$form = $this->createFormBuilder()
    ->add('chars', 'collection', array(
        'type' => new CharacterType(),
        'allow_add' => true,
        'allow_delete' => true,
        'prototype_name' => '__char_prot__'
    ))
    ->getForm();

    # example data
    $form->setData(
        array(
            'chars' => array(
                array('options' => array(), 'char_desc' => 1),
                array('options' => array(), 'char_desc' => 2),
            ),
        )
    );

и вам прототипы

<div
    id="prots"
    data-prototype-opt="{{ form_widget(form.chars.vars.prototype.children['opts'].vars.prototype) | e }}"
    data-prototype-char="{{ form_widget(form.chars.vars.prototype) | e }}"
>
</div>

а затем визуализировать коллекцию, как в этом пример или переопределить collection_widget блок

{% for char in form.chars %}
    {{ form_row(char.char_desc) }}
    <label for="">opts</label>
    {% for opt in char.opts %}
        {{ form_row(opt.text) }}
    {% endfor %}
{% endfor %}

как сохранить его

используйте базу данных nosql, если можете. Или использовать EAV модели для реляционных баз данных. Но если вам не нужно искать параметры или сортировать их, вы можете сохранить сериализованный массив в базе данных и использовать тип доктрины array


добавлять к Б. Алексейответ, мне обычно не нужно использовать prototype.children['opts'] для того, чтобы иметь доступ к прототипу для коллекции. Я просто использую prototype.<collection_name> следующим образом:

<div
    id="prots"
    data-prototype-opt="{{ form_widget(form.chars.vars.prototype.opts.vars.prototype) | e }}"
    data-prototype-char="{{ form_widget(form.chars.vars.prototype) | e }}"
>
</div>