Symfony 3.3表单 - EntityType字段不选择选项

时间:2017-12-06 02:25:38

标签: forms symfony symfony-3.3

由于某些未知原因,即使列的名称匹配且数据通过,EntityType表单字段也不会在提交时显示所选选项。

我已经创建了一个表单,用于选择一些可以过滤产品列表的值。

<?php namespace AppBundle\Filter;

use AppBundle\Entity\ProductCategory; 
use AppBundle\Repository\ProductCategoryRepository; 
use Symfony\Bridge\Doctrine\Form\Type\EntityType; 
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface;

class ProductFilterType extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('id', null, [
                'required'   => false,
                'label'      => 'SKU'
            ])
            ->add('productCategory', EntityType::class,
                array(
                    'class' => ProductCategory::class,
                    'choice_label' => 'name',
                    'choice_value' => 'id',
                    'placeholder' => '',
                    'label_attr' => array('title' => 'Category for this product'),
                    'query_builder' => function (ProductCategoryRepository $v) {
                        return $v->createQueryBuilder('v')
                            ->orderBy('v.name',' ASC');
                    }
                ))
            ->add('name', null, [
                'required'   => false,
            ])
            ->add('description', null, [
                'required'   => false,
            ])


        ;
    }


    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'app_bundle_product_filter_type';
    } }

表单按预期呈现,并将帖子提交到同一URL,该URL根据从请求收到的值进行过滤。

没问题。

但是,重新呈现表单时,不再选择在表单筛选器提交之前选择的选项。所有其他投入都在重新填充。

enter image description here

我注意到当我使用绑定到实体的表单(即:编辑并保存实体)并使用ConfigureOptions方法设置数据类时,EntityType表单字段的工作方式是预期。但是,我需要它在这种情况下工作,其中整体表单不绑定到实体。

编辑: 做这些步骤对我有用......但似乎有点奇怪。

将实体管理器注入表单构造函数:

public $em;

public function __construct(EntityManager $em) {
    $this->em = $em;
}

然后更新EntityType表单字段以根据数组值获取对象:

->add('productCategory', EntityType::class,
            array(
                'class' => ProductCategory::class,
                'choice_label' => 'name',
                'choice_value' => 'id',
                'placeholder' => '',
                'label_attr' => array('title' => 'Category for this product'),
                'data' =>  $this->em->getReference("AppBundle:ProductCategory",
                    isset($options['data']['productCategory']) ? $options['data']['productCategory'] : 0),
                'query_builder' => function (ProductCategoryRepository $v) {
                    return $v->createQueryBuilder('v')
                        ->orderBy('v.name',' ASC');
                }
            ))

...

2 个答案:

答案 0 :(得分:2)

另一种解决方案是使用Data Transformer

data类型中删除productCategory属性,并在build方法的末尾添加数据转换器:

    $builder->get('productCategory')
        ->addModelTransformer(new CallbackTransformer(
            function ($id) {
                if (!$id) {
                    return;
                }

                return $this->em->getRepository('AppBundle:ProductCategory')->find($id);
            },
            function($category) {
                return $category->getId();
            }
        ));

如果在多个地方使用相同的变换器,则可以将其提取到自己的类中。

答案 1 :(得分:0)

我的解决方法是这样的...... 将数据和实体管理器传递给formType。

$form = $this->createForm(new xxxType($this->get('doctrine.orm.entity_manager')), xxxEntity, array(
        'method' => 'POST',
        'action' => $this->generateUrl('xxxurl', array('id' => $id)),
        'selectedId' => xxxId,
    ));

表单中的setDefaultOptions类型初始化为selectedId的空数组

$resolver->setDefaults(array(
        'data_class' => 'xxx',
        'selectedId' => array()
    ));

并在构建器

->add('productCategory', EntityType::class,
            array(
                'class' => ProductCategory::class,
                'choice_label' => 'name',
                'choice_value' => 'id',
                'placeholder' => '',
                'label_attr' => array('title' => 'Category for this product'),
                'query_builder' => function (ProductCategoryRepository $v) {
                    return $v->createQueryBuilder('v')
                        ->orderBy('v.name',' ASC');
                },
                'data'=>$this->em->getReference("xxx",$options['selectedId'])
            ))

有关详细信息,您可以看到此答案Symfony2 Setting a default choice field selection