Symfony 2 - 在preSubmit事件订阅者上添加表单元素的错误

时间:2015-08-14 14:30:45

标签: php symfony doctrine-orm

我在表单的事件订阅者中有一个preSubmit事件,对于特定情况,我想在表单字段中添加错误。订阅者中的方法如下:

public function onPreSubmit(FormEvent $event)

{ 
  $sourceData = $event->getData();
  $form       = $event->getForm();
  $identifier = &$sourceData['identifier'];

  if ($identifier) {

    if ($this->identifierIsUrl($identifier)) {
      $parser     = $this->getIdParser();
      $identifier = $parser->getIdentifier($identifier);

      if (is_null($identifier)) {
        $form->get('identifier')->addError(new FormError('You have either entered an incorrect url for the source or it could not be parsed'));
      }
    }

    $event->setData($sourceData);
    }    
}

但是,当我在视图中打印表单错误时,它是空的。是否可以在preSubmit事件中执行此操作?我看错了吗?

3 个答案:

答案 0 :(得分:7)

此问题与Symfony\Component\Form\Form::submit方法有关,该方法会删除PRE_SUBMIT事件后分配的所有表单字段特定错误。

Form::submit期间,它会迭代所有表单子对象(这些对象也是其他答案所指出的Form个对象)并单独调用它们的submit方法。导致在父{q} 1}事件期间添加的表单元素错误被重置为空数组。

这就是为什么您可以在父PRE_SUBMIT事件中使用$form->addError()或将表单元素设置为PRE_SUBMIT,它将显示为父表单错误,但不会显示为特定表单元件。

这是在不查看Symfony Forms的整个代码库的情况下发生的示例。

error_bubbling  => true

因此导致

class Form 
{

     public function addError($error) 
     {
          if($this->parent && $this->config->getErrorBubbling()) {
              $this->parent->addError($error); //element had error_bubbling => true, attach the error to the parent.
          } else {
              $this->errors[] = $error; //add it to the current object's errors array
          }
    }

    public function submit() 
    {
         $this->errors = array(); //resets the errors of the current object
         $this->preSubmitEvent();

         foreach($this->children as $child) {
             $child->submit(); //errors in child object are reset
         }
    }
}

要解决此问题,您可以直接向表单元素添加Form: submitMethod: preSubmitEvent children: submitMethod: preSubmitEvent 事件,以验证该元素并向其中添加错误。

PRE_SUBMIT

然后相应地更改public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('identifier', Form\TextType::class); //... $builder->get('identifier')->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'validateIdentifier']); } 方法。

onPreSubmit

答案 1 :(得分:0)

如果您查看Form::submit(),应该可以看到错误在之前重置 PRE_SUBMIT数据被调度。此外,Validation Listener不会重置表单上的错误,而Violation Mapper会将错误添加到表单中。而AFIK没有任何监听器可以重置表单的错误。所以也许你做错了什么。

答案 2 :(得分:0)

错误可能不会在您的布局中显示。

要进行调试,请确保您的表单实际上因自定义检查而无效(如果您显示控制器我可以帮助您使用实际代码)。

如果这实际上是您的问题,您可能需要在字段定义中添加error_bubbling => true