如何将模型转换器应用于Symfony2表单中的集合项


How can I apply a Model Transformer to collection items in Symfony2 forms?

上下文

我有一个类型为collection的Symfony2表单字段,其中集合项为entity类型。我使用Symfony 2.7.

问题是

到目前为止它是有效的,但是在这种情况下,我必须像Symfony Cookbook中描述的那样对那些集合项应用模型数据转换器。我使用以下代码片段:

<?php
$builder
    ->add(
        $builder
            ->create('items', 'collection', array(
                'type' => 'entity',
                'options' => array(
                    'class' => 'AppBundle:Item',
                    'property' => 'name',
                    'label' => 'Item',
                ),
                'label' => 'Items',
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'prototype' => true,
                'required' => false,
            ))
            // $options['em'] is the entity manager
            ->addModelTransformer(new ItemToNumberTransformer($options['em']))
    )
;

不幸的是,这将模型转换器应用于整个集合,而不是其中的一个Item项。作为一种解决方案,我修改了转换器,使其也可以处理项目/id数组,而不仅仅是单个项目/id,但这看起来像是处理此问题的错误位置。在我看来,这更像是一个语法问题。

问题是

有人知道如何将模型转换器应用于集合的每个项目吗?或者有人能证实由于Symfony框架的限制,这是不可能的吗?

我想说,而不是创建entity类型的collection,您需要创建自己的类型。

namespace AppBundle'Form'Type;
use Symfony'Component'Form'AbstractType;
use Symfony'Component'Form'FormBuilderInterface;
use Symfony'Component'OptionsResolver'OptionsResolverInterface;
use Doctrine'ORM'EntityManager;
/* Other use statements */
class ItemEntityType extends AbstractType
{
    /**
     * @var 'Doctrine'ORM'EntityManager
     */
    protected $em;
    public function __construct(EntityManager $em)
    {
        $this->em = $em
    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addModelTransformer(new ItemToNumberTransformer($this->em));
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'class'    => 'AppBundle:Item',
            'property' => 'name',
            'label'    => 'Item',
        ));
    }
    public function getParent()
    {
        return 'entity';
    }
    public function getName()
    {
        return 'appbundle_item_entity';
    }
}

然后将其定义为服务

app/config/services.yml

services:
    form.type.model.item_entity:
        class: AppBundle'Form'Type'ItemEntityType
        arguments: ["@doctrine.orm.entity_manager"]
        tags:
          - {name: form.type, alias: appbundle_item_entity}

现在你可以为你的集合指定这个类型

$builder
    ->create('items', 'collection', array(
        'type' => 'appbundle_item_entity'
        'label' => 'Items',
        'allow_add' => true,
        'allow_delete' => true,
        'delete_empty' => true,
        'prototype' => true,
        'required' => false,
    ))

披露:我还没有测试过这个,但它应该工作

您应该为Item实体创建一个Type,对其应用转换器,然后将其用作集合的类型。