Symfony2:如何在提交后删除侦听器中的表单字段
Symfony2 : How to remove form field in listener, after submit
我在我的 FormType 中遇到了问题。
基于"Product"实体,这个from有一个叫做"ProductCriteria"的字段,它是一个基于"ProductCriteriaType"(Form)的集合。
我的 productCriteria 模型包含一个 "deleted" 属性,用于处理该实体的逻辑抑制。如果它设置为 true,那么我不希望 productCriteria 表单类型显示在产品表单类型中。如果设置为false,那么我想在产品Form Type中显示,你懂的
我在表单的 PRE_SET_DATA 事件中写了这个,效果非常好:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
$product = $event->getData();
/** @var PersistentCollection $productCriteriasFields */
$productCriteriasFields = $product->getProductCriterias();
/** @var ProductCriteria $productCriteria */
foreach($productCriteriasFields as $productCriteria){
if($productCriteria->getDeleted()){
$productCriteriasFields->removeElement($productCriteria);
}
}
});
我的字段在表单中设置为 true/false,当我访问 FormType 时,它没有按预期显示 delete-true 字段。
唯一的问题是:
当我刚刚修改了一个 'deleted' 值时,控制器不会在表单 isValid() 时重定向到另一个页面。它只是再次呈现 FormType,并且表单不包含我的修改(但它们在数据库中!)。如果我刷新页面 (F5),我确实得到了我想要的修改。
如何解决这个问题?我尝试添加一个 'POST_SUBMIT' 函数,处理这样的表单字段:
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event){
/** @var Product $data */
$product = $event->getForm()->getData(); //this was supposed to do the trick
$form = $event->getForm();
/** @var ProductCriteria $productCriteria */
for($i = 0; $i < count($product->getProductCriterias()); $i++){
if($product->getProductCriterias()[$i]->getDeleted()){
ladybug_dump("unsetting one field ! ");
unset($form->get('productCriterias')[$i]);
}
}
但没有任何效果。任何想法?非常感谢。
编辑
控制器的代码(它是一个抽象的代码:我项目的archi,不是一个选择):
/** @var EditableEntityInterface $entity */
$entity = $this->entityService->getEntityById($itemId);
$form = $this->createForm('admin' . $this->entityService->getEntityName(), $entity);
$form->handleRequest($this->get('request'));
$submitSuccess = false;
if ($form->isValid()) {
$this->entityService->save($form->getData());
$submitSuccess = true;
}
$template = $this->getActionTemplate($this->entityService->getEditTemplate());
return $this->render($template, array(
'item' => $entity,
'form' => $form->createView(),
'entityService' => $this->entityService,
'submitSuccess' => $submitSuccess
));
好吧,我终于开始工作了!!问题出在我修改的控制器代码中:
$form->handleRequest($this->get('request'));
$submitSuccess = false;
if ($form->isValid()) {
$this->entityService->save($form->getData());
$submitSuccess = true;
// Data sync hardened !
$entity = $this->entityService->getEntityById($itemId);
$form = $this->createForm('admin' . $this->entityService->getEntityName(), $entity);
}
我强制表格由我们刚刚保存的实体重新水合,以确保它不会在之前的 $request 中获取之前的数据。
但是仍然......这太不可思议了我无法通过使用表单事件来实现这一点。该文档非常糟糕,只显示了非常简单的示例。对于那些可能需要更多关于表单事件的信息的人,我可以推荐这个:
http://symfony.com/doc/current/components/form/form_events.html#component-form-event-table
看看核心中的 class :
Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener.php
这就是您可以使用主要 FormEvents 在表单上执行的几乎所有操作。
我在我的 FormType 中遇到了问题。 基于"Product"实体,这个from有一个叫做"ProductCriteria"的字段,它是一个基于"ProductCriteriaType"(Form)的集合。
我的 productCriteria 模型包含一个 "deleted" 属性,用于处理该实体的逻辑抑制。如果它设置为 true,那么我不希望 productCriteria 表单类型显示在产品表单类型中。如果设置为false,那么我想在产品Form Type中显示,你懂的
我在表单的 PRE_SET_DATA 事件中写了这个,效果非常好:
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
$product = $event->getData();
/** @var PersistentCollection $productCriteriasFields */
$productCriteriasFields = $product->getProductCriterias();
/** @var ProductCriteria $productCriteria */
foreach($productCriteriasFields as $productCriteria){
if($productCriteria->getDeleted()){
$productCriteriasFields->removeElement($productCriteria);
}
}
});
我的字段在表单中设置为 true/false,当我访问 FormType 时,它没有按预期显示 delete-true 字段。
唯一的问题是: 当我刚刚修改了一个 'deleted' 值时,控制器不会在表单 isValid() 时重定向到另一个页面。它只是再次呈现 FormType,并且表单不包含我的修改(但它们在数据库中!)。如果我刷新页面 (F5),我确实得到了我想要的修改。 如何解决这个问题?我尝试添加一个 'POST_SUBMIT' 函数,处理这样的表单字段:
$builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $event){
/** @var Product $data */
$product = $event->getForm()->getData(); //this was supposed to do the trick
$form = $event->getForm();
/** @var ProductCriteria $productCriteria */
for($i = 0; $i < count($product->getProductCriterias()); $i++){
if($product->getProductCriterias()[$i]->getDeleted()){
ladybug_dump("unsetting one field ! ");
unset($form->get('productCriterias')[$i]);
}
}
但没有任何效果。任何想法?非常感谢。
编辑 控制器的代码(它是一个抽象的代码:我项目的archi,不是一个选择):
/** @var EditableEntityInterface $entity */
$entity = $this->entityService->getEntityById($itemId);
$form = $this->createForm('admin' . $this->entityService->getEntityName(), $entity);
$form->handleRequest($this->get('request'));
$submitSuccess = false;
if ($form->isValid()) {
$this->entityService->save($form->getData());
$submitSuccess = true;
}
$template = $this->getActionTemplate($this->entityService->getEditTemplate());
return $this->render($template, array(
'item' => $entity,
'form' => $form->createView(),
'entityService' => $this->entityService,
'submitSuccess' => $submitSuccess
));
好吧,我终于开始工作了!!问题出在我修改的控制器代码中:
$form->handleRequest($this->get('request'));
$submitSuccess = false;
if ($form->isValid()) {
$this->entityService->save($form->getData());
$submitSuccess = true;
// Data sync hardened !
$entity = $this->entityService->getEntityById($itemId);
$form = $this->createForm('admin' . $this->entityService->getEntityName(), $entity);
}
我强制表格由我们刚刚保存的实体重新水合,以确保它不会在之前的 $request 中获取之前的数据。 但是仍然......这太不可思议了我无法通过使用表单事件来实现这一点。该文档非常糟糕,只显示了非常简单的示例。对于那些可能需要更多关于表单事件的信息的人,我可以推荐这个: http://symfony.com/doc/current/components/form/form_events.html#component-form-event-table 看看核心中的 class : Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener.php 这就是您可以使用主要 FormEvents 在表单上执行的几乎所有操作。