由于某些未知原因,即使列的名称匹配且数据通过,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根据从请求收到的值进行过滤。
没问题。
但是,重新呈现表单时,不再选择在表单筛选器提交之前选择的选项。所有其他投入都在重新填充。
我注意到当我使用绑定到实体的表单(即:编辑并保存实体)并使用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');
}
))
...
答案 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