上下文
我有一个类型为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,对其应用转换器,然后将其用作集合的类型。