【问题标题】:How can I apply a Model Transformer to collection items in Symfony2 forms?如何将模型转换器应用于 Symfony2 表单中的集合项目?
【发布时间】:2015-05-29 12:58:31
【问题描述】:

上下文是

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

问题是

到目前为止它可以工作,但在这种情况下,我必须将模型数据转换器应用于这些集合项,如 in the Symfony Cookbook 所述。我用这个代码sn-p:

<?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']))
    )
;

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

问题是

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

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    我想说,您需要创建自己的类型,而不是创建 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,
        ))
    

    披露:我没有对此进行测试,但它应该工作。

    【讨论】:

    • 谢谢!这看起来是正确的方法。我会尝试一下。下一次,因为我刚刚意识到带有multiple 选项的简单实体字段可以很好地完成给定任务。愚蠢的我。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 2012-07-14
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 2011-04-06
      • 1970-01-01
      相关资源
      最近更新 更多