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 在表单上执行的几乎所有操作。