这是之前问题的延续 Symfony2 Custom Form Type or Extension
我正在尝试将自定义字段类型“Product”附加到订单上。名称字段将包含产品名称,而ID字段将包含产品ID。
我使用FormEvents :: PRE_SET_DATA尝试填充数据,但会抛出一个错误,getData()返回Form\Type\ProductAutoCompleteType。
我该如何纠正代码?
OrderType拥有以下内容:
我使用FormEvents :: PRE_SET_DATA尝试填充数据,但会抛出一个错误,getData()返回Form\Type\ProductAutoCompleteType。
我该如何纠正代码?
OrderType拥有以下内容:
$builder->add('product', new Type\ProductAutoCompleteType(), array(
'data_class' => 'Acme\TestBundle\Entity\Product'
));
产品自动完成类型:
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()成员函数。
控制器
$em = $this->getDoctrine()->getManager();
$order = $em->getRepository('AcmeTestBundle:Order')->find(6);
$form = $this->createForm(new OrderType(), $order);
更新2
在更改字段[product][id]并提交表单后,我现在收到以下错误信息,我认为这是因为字段名称是[product][id]而不是[product]导致的?
在类“Proxies__CG\Acme\TestBundle\Entity\Product”中,属性"id"和方法"setId()"、"set()"或"__call()"中没有一个存在且具有公共访问权限。
更新3
现在我已经成功将数据提交到控制器,在我的控制器上提交时,我不得不添加以下内容,以这种方式进行验证和附加产品看起来很混乱,这是正确的方法吗?
$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'));
}
}
PRE_SET_DATA
,我认为您还没有在其中使用$order。尝试使用POST_SET_DATA
事件来处理这种情况。(我希望在让您实现表单监听器时不会将您推向完全错误的方向。可能是我没有看到您完整的用例。) - Debreczeni András