Symfony2在一个Form中表示同一类的多个实体


Symfony2 multiple Entities of same class in one Form

我想要呈现一个具有同一类的多个实体的表单。我将显示两个字段,价格(类型=文本)和启用(类型=复选框)。

我不知道我会有多少这样的实体,所以表单必须动态地获取它们。

我试着做了以下

public function buildForm(FormBuilderInterface $builder, array $options)
{
        $builder
            ->add('price', 'text', array(
                'label' => 'Price',
                'required' => true
            ))
            ->add('enabled','checkbox',array(
                'label'     => 'Use this currency',
            ))
        ;    
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class'        => 'Osiris'Entity'Pricing',
        'csrf_protection'   => false
    ));
}
public function getName()
{
    return 'pricingtype';
}

在我的控制器中,我创建了这样的表单:

$pricingForm = $this->createFormBuilder($prices)
               ->add('items','collection',array(
                   'required' => false,
                   'prototype' => true,
                   'type'    => new PricingType(),
               ))
                ->getForm()
            ;

在我的树枝上我做:

{% for price in form_pricing %}
    <h2>Price</h2>
    <div class="row">{{ form_widget(price) }}</div>
{% endfor %}

然而,它只提供了h2价格和class=row的空div。我觉得我已经走了一半,但我不知道如何继续前进。如果有人知道如何在提交时获得字段,我将非常感激。

我找到了解决方案

我在Controller中创建表单的方式是错误的!我不得不做以下事情:

$pricingForm = $this->createFormBuilder(array('prices'=>$prices))
                ->add('prices','collection',array(
                    'required'       => true,
                    'allow_add'      => true,
                    'type'           => new PricingType(),
               ))
                ->getForm()
            ;

"allow_add=>true"在处理集合时是必需的,否则它将NOT将任何PricingType实体集合添加到表单中。

然后,因为表单是在控制器"$this->createFormBuilder(array('prices'=>$prices))"中构建的,所以$prices数组必须作为一个数组传递,其数组注释名与"->add('prices','collection',array(...)"中使用的数组注释名相同,即'prices',因此Symfony将知道在哪里绑定什么。$prices是定价对象array(0 => new Pricing())的数组。

在我的PricingType中,我有:

class PricingType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('price', 'text', array(
                'label' => false,
                'required' => true
            ))
            ->add('enabled','checkbox',array(
                'label'     => 'Use this currency',
            ))
        ;
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'        =>  'XXX'XXX'Entity'Pricing',
            'csrf_protection'   => false
        ));
    }
    public function getName()
    {
        return 'pricingtype';
    }
}

这里我需要控制标签属性。我找不到它的路(如果有人知道请张贴如何)。我覆盖我的小树枝模板如下:

在顶部,我们需要下一行代码:

    {% form_theme form_pricing _self %}

然后覆盖行和小部件如下(调试起来简直是噩梦):

{% block _form_prices_entry_row %}
    {% spaceless %}
        {{ form_widget(form) }}
    {% endspaceless %}
{% endblock %}
{% block _form_prices_entry_widget %}
    {% spaceless %}
        {{ form_row(form.price, { 'label' : form.vars.value.getCurrency().getTitle() } ) }}
        {{ form_row(form.enabled) }}
    {% endspaceless %}
{% endblock %}

然后在主体中,按如下方式渲染表单元素:

{% for price in form_pricing.prices %}
                    <div class="price-row">{{ form_row(price) }}</div>
                {% endfor %}

我真的希望这对你们有帮助。调试真是一场噩梦,尤其是调试trick文件,多亏了我聪明的同事,我才做到了。

我认为您在Twitch文件中错过了一个for循环检查此示例:

    {# store the prototype on the data-prototype attribute #}
    <ul id="email-fields-list" data-prototype="{{ form_widget(form.emails.vars.prototype)|e }}">
    {% for emailField in form.emails %}
        <li>
            {{ form_errors(emailField) }}
            {{ form_widget(emailField) }}
        </li>
    {% endfor %}
    </ul>

看到这个循环,我认为你需要添加到你的小树枝文件中。

除了循环,您还需要添加JavaScript

检查此链接:

http://symfony.com/doc/current/reference/forms/types/collection.html#adding-和删除项目

检查完整的代码。它将帮助您使用集合字段类型从单个实体类生成多个实体窗体。