【问题标题】:symfony2 multiple nested forms prototypesymfony2 多个嵌套表单原型
【发布时间】:2013-05-05 10:12:46
【问题描述】:

我想在另一个集合类型中包含一个集合类型。 它应该看起来像这样:

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

任何想法我该怎么做?还有什么是最好的保存方式

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

  <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 "Symfony\Component\Form\FormView" 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')) 
        ;

一级原型,工作正常。

【问题讨论】:

  • 大家好。我正在尝试开发类似的表单,以创建(新)和编辑嵌套实体。我为实体 A 1:m B 1:m C 开发了一个玩具 Symfony 3.1 捆绑包。它似乎有效。如果您检查并建议如何改进/重写它,我将不胜感激。请参阅github.com/mario6097/SimpleBundle。谢谢。

标签: forms symfony prototype nested-forms


【解决方案1】:

表单和原型

您需要保留来自不同集合的两个原型。 Symfony 提供将它们存储在 div 标签的 data-prototype 属性中,该属性包装了集合。在你的情况下,它非常低效。所以你可以在某处的空 div 中手动渲染它

例如你有字符形式

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>

然后像 example 那样渲染集合或覆盖 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

【讨论】:

  • 我的 data-prototype2 有问题:“Symfony\Component\Form\FormView”类型的对象(使用 ArrayAccess)中的键“0”不存在。
  • 对不起,设置新版本的 symfony 并看到错误。更新我的答案。
  • 谢谢。只有在您的回答中,我才发现如何以嵌套形式访问原型:data-prototype-opt="{{ form_widget(form.chars.vars.prototype.children['opts'].vars.prototype) | e }}"
  • 一些奇怪的行为:嵌套表单原型仅在表单渲染之前可用!也许我的代码中有一些错误,也许我会节省一些时间来研究:)
  • 原型的顺序很关键:嵌套最深的应该先出现,然后是它的父级(以相反的顺序)。否则子原型将转到父原型,您将在模板中得到一个空字符串。
【解决方案2】:

除了Alexey B. 的回答,我通常似乎不需要使用prototype.children['opts'] 来访问集合的原型。我只是使用prototype.&lt;collection_name&gt;如下:

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

【讨论】:

  • 这是因为 Twig 使用点符号来访问关联数组索引、同名对象获取方法或对象属性。允许prototype.opts 访问prototype['opts']prototype-&gt;getOpts()prototype-&gt;opts
猜你喜欢
  • 2012-12-02
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 2020-02-21
相关资源
最近更新 更多