我没有找到解决问题的帖子,希望它不会重复。
在Symfony表单中,我声明了一个实体字段。
$form->add($builder->getFormFactory()->createNamed(
'cert_folder_product_factory',
new EntityMultipleType(),
null,
array(
'label' => '',
'mapped' => false,
'class' => 'ProductsBundle:ProductFactory',
'empty_value' => '',
'auto_initialize' => false,
'required' => false,
'label_controls' => array('add' => 'Add Product', 'remove' => 'Remove Product'),
)
));
我希望这个字段在开始时有一个空的实体集合,因为该集合基于其他字段值,因此我不会在声明时放置任何 query_builder 参数。
$form->add($builder->getFormFactory()->createNamed(
'supplier_list',
'entity',
null,
array(
'mapped' => false,
'label' => ' ',
'class' => 'SuppliersBundle:Suppliers',
'empty_value' => '',
'auto_initialize' => false,
'required' => false,
'data' => $data->getSupplierProduct(),
'query_builder' => function(\Ella\SuppliersBundle\Repository\SuppliersRepository $er) {
return $er->createQueryBuilder('q')->andWhere('q.is_delete = 0')->orderBy('q.name', 'asc');
})
)
);
一旦 supplier_list 字段有值,AJAX查询就会检索关联的元素并填充 cert_folder_product_factory 字段的集合。
为了在提交时验证表单并按照建议,我声明 PRE_SUBMIT EventListener来填充字段集合并验证用户选择的值
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($builder, $container) {
$data = $event->getData();
$form = $event->getForm();
if (!$data['supplier_list']) {
return;
}
$supplierId = $data['supplier_list'];
$form->add($builder->getFormFactory()->createNamed(
'cert_folder_product_factory',
new EntityMultipleType(),
null,
array(
'label' => '',
'mapped' => false,
'class' => 'ProductsBundle:ProductFactory',
'empty_value' => '',
'auto_initialize' => false,
'required' => false,
'label_controls' => array('add' => 'Add Product', 'remove' => 'Remove Product'),
'query_builder' => function(\Ella\ProductsBundle\Repository\ProductFactoryRepository $er) use ($supplierId) {
return $er->getProductBySupplier($supplierId);
},
)
)
);
});
一旦我有 supplier_list 字段和表单提交的值,一切正常。但是,正如Symfony文档针对 query_builder 所解释的那样,query_builder param的默认行为是加载所有实体,使加载时间非常长,无需任何操作。
我的解决方法是强制加载一个任意实体
'query_builder' => function (\Ella\ProductsBundle\Repository\ProductFactoryRepository $er) {
return $er->createQueryBuilder('q')->setMaxResults(1);
}
但是这个解决方案完全错误,强制实体集合首先加载0实体的任何正确方法都是错误的?
非常感谢您的帮助。
答案 0 :(得分:0)
仅供参考,简单的做法是将null
作为$supplierId
参数的值传递,不会检索任何结果(仅当您在setParameter()
中传递值时才有效QueryBuilder的)。
我还添加了https://symfony.com/doc/2.7/form/dynamic_form_modification.html#form-events-user-data中描述的formModifier,以避免在不同的EventListener
$formModifier = function (FormInterface $form, $supplierId = null, $productFactories = null) {
$form->add('cert_folder_product_factory', new EntityMultipleType(),
array(
'label' => '',
'mapped' => false,
'class' => 'ProductsBundle:ProductFactory',
'empty_value' => '',
'auto_initialize' => false,
'required' => false,
'label_controls' => array('add' => 'Add Product', 'remove' => 'Remove Product'),
'query_builder' => function(\Ella\ProductsBundle\Repository\ProductFactoryRepository $er) use ($supplierId) {
return $er->getProductBySupplier($supplierId);
},
'data' => (count($productFactories) > 0) ? $productFactories : null,
)
);
};
在PRE_SET_DATA中声明字段
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formModifier, $builder, $container) {
$formModifier($form,
($data->getSupplierProduct()) ? $data->getSupplierProduct()->getId() : null,
(count($data->getProductFactory())) ? $data->getProductFactory() : null
);
}
然后在PRE_SUBMIT中验证表单提交
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($formModifier) {
$data = $event->getData();
$form = $event->getForm();
$formModifier($form,
array_key_exists('supplier_list', $data) ? $data['supplier_list'] : null
);
});