使用值填充Symfony2自定义字段类型 [英] Symfony2 Custom Field Type from Populate with values
问题描述
这是先前问题 Symfony2自定义表单类型或扩展名的后续内容
This is a follow on from the earlier question Symfony2 Custom Form Type or Extension
我正在尝试在订单上附加产品的自定义字段类型.名称字段将包含产品名称,而ID字段将包含产品ID.
I am trying to attach a custom field type for Product on an Order. The name field will contain the product name and the id field the product id.
我正在使用FormEvents :: PRE_SET_DATA尝试填充数据,但会引发错误,getData()返回Form \ Type \ ProductAutoCompleteType.
I am using FormEvents::PRE_SET_DATA to try and populate the data but it throws an error, getData() returns Form\Type\ProductAutoCompleteType.
我该如何更正代码?
OrderType具有以下内容:
OrderType has the following:
$builder->add('product', new Type\ProductAutoCompleteType(), array(
'data_class' => 'Acme\TestBundle\Entity\Product'
));
ProductAutoCompleteType:
ProductAutoCompleteType:
class ProductAutoCompleteType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name');
$builder
->add('id');
/* Turns out this is not needed any more
$builder->addEventListener(
FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$product = $form->getData();
$form
->add('name', 'text', array('mapped' => false, 'data' => $product->getName()));
}
);
*//
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
}
public function getParent()
{
return 'form';
}
public function getName()
{
return 'productAutoComplete';
}
}
已更新
错误:FatalErrorException:错误:在/var/www/symblog/src/Acme/TestBundle/Form/Type/ProductAutoCompleteType.php第26行中的非对象上调用成员函数getProduct()
Error: FatalErrorException: Error: Call to a member function getProduct() on a non-object in /var/www/symblog/src/Acme/TestBundle/Form/Type/ProductAutoCompleteType.php line 26
控制器
$em = $this->getDoctrine()->getManager();
$order = $em->getRepository('AcmeTestBundle:Order')->find(6);
$form = $this->createForm(new OrderType(), $order);
已更新2
更改字段[product] [id]并提交表单后,现在出现以下错误,我认为这是因为字段名称是[product] [id]而不是[product]?
After changing the field [product][id] and submitting the form I now get the following error, I assume this is because the field name is [product][id] and not [product]?
属性"id"或方法"setId()"," set()"或"__call()"都不存在,并且在类"Proxies__CG \ Acme \"中具有公共访问权限TestBundle \ Entity \ Product".
Neither the property "id" nor one of the methods "setId()", "set()" or "__call()" exist and have public access in class "Proxies__CG\Acme\TestBundle\Entity\Product".
已更新3
我现在已经将数据提交给控制器,在提交控制器时,我不得不添加以下内容,以这种方式进行验证和附加产品看起来很麻烦,这是正确的方法吗?
I have it submitting data to the controller now, in my controller on submit I have had to add the following, it looks messy to do validation and attach the product this way, is this the right way?
$data = $request->request->get($form->getName());
if ($data['product']['id']) {
$product = $em->getRepository('AcmeTestBundle:Product')->find($data['product']['id']);
if ($product) {
if ($product->getShop()->getId() != $order->getShop()->getId()) {
$form->get('product')->get('name')->addError(new FormError('Invalid shop product'));
}
$form->getData()->setProduct($product);
} else {
$form->get('product')->get('name')->addError(new FormError('A product must be selected'));
}
}
推荐答案
将所有逻辑放入控制器中不是一个好习惯.您的表单应尽可能多地处理这些表单,以确保这些表单的可重用性.
Putting all your logic into the controller is not a good practice. Your forms should handle as much of this as possible to ensure reusability of these forms.
如果查询的订单中没有相关产品,则$form->getData()
返回null是正常的.
If the Order that you query does not have a related product in it, then it's normal that $form->getData()
returns null.
调试技巧:
输出$form->getData()
的值以检查Product对象.
输出$form->getParent()->getData()
的值以检查父窗体中的Order对象.
Output the value of $form->getData()
to inspect the Product object.
Output the value of $form->getParent()->getData()
to inspect the Order object from the parent form.
验证提示:
如果这种形式的产品可以为空,请确保仅在产品不为空的情况下设置名称字段的数据.
In case a product in this form can be null, make sure that you only set the name field's data if the product is not null.
查询提示:
由于存储库中的findBy
方法不会自动包含相关的product
,因此我建议使用QueryBuilder并进行联接.控制器中的示例:
Since the findBy
method on the repository will not automatically include the related product
, I recommend using a QueryBuilder and make a join. Example in the controller:
$order = $em->getRepository('AcmeTestBundle:Order')
->createQueryBuilder('order')
->select('order, product')
->innerJoin('order.product', 'product')
->where('order.id = :order_id')
->setParameter('order_id', $order_id)
->getQuery()
->getOneOrNullResult();
当然,在控制器中包含太多代码也不是一件好事,因此,一旦工作正常,请使用自定义方法创建一个自定义存储库,并将此代码移到那里.
Of course, having so much code in your controller is not great either, so once you get your stuff working, create a custom repository with a custom method and move this code there.
在您的实体中:
/**
* @Entity(repositoryClass="Acme\TestBundle\Repository\OrderRepository")
*/
class Order {
在您的存储库中
class OrderRepository {
public function findByIdWithProduct() {
// $order = $this->createQueryBuilder...
return $order;
}
}
这篇关于使用值填充Symfony2自定义字段类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!