symfony2 多嵌套表单原型 [英] symfony2 multiple nested forms prototype

查看:39
本文介绍了symfony2 多嵌套表单原型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在另一个集合类型中包含一个集合类型.它应该是这样的:

只使用一个集合可以正常工作,但我需要编辑外部表单的原型,因此它为每一行呈现内部表单的原型.

任何想法我怎么能做到这一点?还有什么是最好的保存方式

现在我正在尝试渲染嵌套表单的原型:

 <ul class="characteristics-container" data-prototype="{{ form_widget(form.characteristics.vars.prototype)|e }}" data-prototype-options="{{ form_widget(form.characteristics.options.vars.prototype|e ) }}">{# 遍历每个现有标签并呈现其唯一字段:name #}{% 用于 form.characteristics 中的特征 %}<li>{{ form_row(characteristic.name) }}</li><div class="characteristics-options">{% 用于选择 form.characteristics.options %}{% 结束为 %}

{% 结束为 %}

它在 form_widget(form.characteristics.options.vars.prototype|e

对象SymfonyComponentFormFormView"的方法选项"不存在于

我尝试了特性[0],它说密钥不存在

这是我的表单类:

PromotionType(基本形式)

$builder->add('特征','集合', 数组('标签' =>'特征','类型' =>新的 PromotionCharacteristicType(),'allow_add' =>真的,'allow_delete' =>真的,'by_reference' =>错误的))

PromotionCharacteristicType

 $builder->add('name',NULL, array('label' =>'Nome'))->add('options', 'collection', array('类型' =>新的 PromotionCharacteristicOptionType(),'allow_add' =>真的,'allow_delete' =>真的,'原型' =>真的,'by_reference' =>错误的,));

PromotionCharacteristicOptionType

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

一级原型,工作正常.

解决方案

表单和原型

您需要保留来自不同集合的两个原型.Symfony 提供将它们存储在 div 标签的数据原型属性中,该属性包装了集合.在你的情况下,它非常低效.所以你可以在那里的空 div 中手工渲染它

例如你有字符形式

class CharacterType 扩展 AbstractType{公共函数 buildForm(FormBuilderInterface $builder, array $options){$builder->add('opts', 'collection', array('类型' =>新选项类型(),'allow_add' =>真的,'allow_delete' =>真的,'原型' =>真的,'prototype_name' =>'__opt_prot__'));$builder->add('char_desc', 'text');}公共函数 getName(){返回字符";}}

然后创建具有字符集合的表单

$form = $this->createFormBuilder()->add('chars', 'collection', array('类型' =>新的字符类型(),'allow_add' =>真的,'allow_delete' =>真的,'prototype_name' =>'__char_prot__'))->getForm();# 示例数据$form->setData(大批('字符' =>大批(数组('选项' => 数组(),'char_desc' => 1),数组('选项' => 数组(),'char_desc' => 2),),));

并获得原型

然后像这个示例 或覆盖 collection_widget 块

{% for char in form.chars %}{{ form_row(char.char_desc) }}<label for="">opts</label>{% 选择加入 char.opts %}{{ form_row(opt.text) }}{% 结束为 %}{% 结束为 %}

如何保存

如果可以,请使用 nosql 数据库.或者对关系数据库使用 EAV 模型.但是如果你不需要搜索选项,或者对它们进行排序,你可以在数据库中存储一个序列化的数组并使用学说类型array

I want to include a collection type inside another collection type. It should look like this:

Using just one collection works fine, but I need to edit the prototype of the outer form, so it renders the prototype of the inner form for each line.

Any ideas how could I do that? Also what would be the best way to save

EDIT: Now I am trying to render the prototype of the nested form:

  <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>

It gives error in form_widget(form.characteristics.options.vars.prototype|e

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

I tried characteristics[0], and it says the key doesnt exist

Here are my form classes:

PromotionType (the base form)

$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')) 
        ;

The first level prototype, works fine.

解决方案

forms and prototype

You need to keep two prototypes from different collections. Symfony offers to store them in a data-prototype attribute of div tag, which wrap the collection. In your situation it`s very inefficient. So you can just render it by hand in empty div somethere

Example you have characters form

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';
    }
}

Then create form that has characters collection

$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),
            ),
        )
    );

and get prototypes

<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>

And then render collection like in this example or override collection_widget block

{% 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 %}

how to save it

Use nosql database if you can. Or use EAV model for relation databases. But if you do not need to search through the options, or sort them, you can store a serialized array in the database and use the doctrine type array

这篇关于symfony2 多嵌套表单原型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆