Symfony2 Choice List:从子元素中获取选择

Symfony2 ChoiceList: Get the choise from the child element

Symfony2 ChoiceList: 从子元素中获取选项

我正在构建表格,我想为客户提供一些额外的产品。

我首先想到的是使用选择字段类型,尤其是当我可以直接将所选实体作为输出值时。

$productNames = array();
    foreach ($this->products as $product){
        $productNames[] = $product->getName();
    }

    $builder->add('products', 'choice', array(
            'choice_list' => new ChoiceList(
                 $this->products,
                 $productNames
    ),
    'required' => false,
    'expanded' => true,
    'multiple' => true
));

但是我需要渲染的不仅仅是标签,所以我需要访问视图中渲染的实体。

{% for child in form.products %}         
    <label for="{{ child.vars.id }}">
        {{ form_widget(child) }}{{ products[loop.index0].getDescription()}}
    </label>
{% endfor %}

所以我问是否有更好的方法从视图中的子元素中获取实体(选择)。

我能想到的唯一方法是 create your own form type(从选择类型扩展),这将呈现您需要的额外信息。

因此请创建您的表单类型:

class MyFormType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        // set the options as you do above
        $resolver->setDefaults([ 'expanded' => true, ]);

        // this exposes a "products" option when adding this formtype
        $resolver->setRequired(['products']);
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach ($options['products'] as $product) {
            // build your form as you do in your example above
        }
    }

    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        // this makes the "products" array available in your view
        $view->vars['products'] = $options['products'];
    }

    public function getParent()
    {
        return 'choice';
    }

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

然后在您自己的表单中添加以下字段类型:

$builder->add('my_form_type', [ 'products' => $products ]);

然后您为您的字段创建一个视图:

{% block my_form_type_widget %}
    {% for child in form %}
        {{ form_widget(child) }} {{ products[loop.index0].description }}
    {% endfor %}
{% endblock %}

我已经忽略了其他一些细节(将表单类型添加到您的服务描述中,将您的视图设置为 Twig 资源),因为 cookbook entry 中涵盖了所有这些细节。上面的设置确实要求表单选项与 $products 数组的顺序相同——否则 loop.index0 将不匹配。解决此问题的唯一方法是执行类似 Entity 字段类型的操作,这非常复杂,但如果您想要进一步开发,这是一个很好的起点。

带有custom query的实体字段类型怎么样,大致是这样的:

$builder->add('products', 'entity', array(
    'class' => 'YourBundle:Product',
    'query_builder' => function (EntityRepository $er) {
        return $er->createQueryBuilder('p')
            ->orderBy('p.name', 'ASC');
    },
    'expanded' => true,
    'multiple' => true
    'choice_label' => 'labelForSelectbox'
));

查询获取所有产品,因此您可能不得不以某种方式用 where() 限制结果。

要使其正常工作,您必须在 Product 实体中添加此 getter:

public function getLabelForSelectbox()
{
    return $this->getName() . $this->getDescription();
}

Twig 实施结束于:

{{ form_row(form.products) }}