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

时间:2015-08-20 04:39:53

标签: php symfony doctrine-orm twig

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

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

2 个答案:

答案 0 :(得分:1)

我能想到这样做的唯一方法是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字段类型的操作,这种类型非常复杂,但如果您想进一步开发,这是一个很好的起点。

答案 1 :(得分:0)

实体字段类型如何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) }}