【问题标题】:Symfony2 : How to remove form field in listener, after submitSymfony2:提交后如何在侦听器中删除表单字段
【发布时间】:2015-03-10 18:15:16
【问题描述】:

我在我的 FormType 中遇到了问题。 基于“Product”实体,this from有一个名为“ProductCriteria”的字段,它是一个基于“ProductCriteriaType”(Form)的集合。

我的 productCriteria 模型包含一个“已删除”属性,用于处理该实体的逻辑抑制。如果它设置为 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 字段。

唯一的问题是: 当我刚刚修改了“已删除”值时,当表单为 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
));

【问题讨论】:

  • 你能告诉我们控制器操作代码吗?
  • instead of this" /** @var Product $data */ $product = $event->getForm()->getData(); //这应该可以解决问题 $form = $event->getForm();"试试这个: $form = $event->getForm(); $data = $event->getData();
  • 已经试过了,不行。我关心的部分是: if($product->getProductCriterias()[$i]->getDeleted()){ ladybug_dump("unsetting one field !"); unset($form->get('productCriterias')[$i]); }
  • 我不确定如何删除集合字段中的子表单,我怀疑我的控制器会获取以前的实体数据
  • 你试过 $form->remove('field_name');删除字段?

标签: forms symfony events field listener


【解决方案1】:

好的,我终于可以开始工作了!问题出在我修改的控制器代码中:

$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 并在核心中查看此类: Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener.php 这几乎就是您可以使用主要 FormEvents 对表单执行的所有操作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-03
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多