我在表单的事件订阅者中有一个 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);
}
}
但是当我在 View 中打印表单错误时,它是空的。是否可以在 preSubmit 事件中执行此操作?我是不是看错了?
最佳答案
此问题与 Symfony\Component\Form\Form::submit
方法有关,该方法删除了在 PRE_SUBMIT
事件之后指定的所有表单字段特定错误。
在 Form::submit
期间,它遍历所有表单子(monad)对象(它们本身也是 Form
对象,如其他答案所述)并调用它们的 单独提交
方法。导致在父级的 PRE_SUBMIT
事件期间添加的表单元素错误被重置为空数组。
这就是为什么您可以在父 PRE_SUBMIT
事件中使用 $form->addError()
或将表单元素设置为 error_bubbling => true
,它将显示为父表单错误,但不会显示到特定的表单元素。
这里是一个例子,说明了在没有查看 Symfony Forms 的整个代码库的情况下会发生什么。
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
方法。
public function validateIdentifier(FormEvent $event)
{
$identifier = $event->getData();
$element = $event->getForm();
if ($identifier) {
if ($this->identifierIsUrl($identifier)) {
$parser = $this->getIdParser();
$identifier = $parser->getIdentifier($identifier);
if (null === $identifier) {
$element->addError(new FormError('You have either entered an incorrect url for the source or it could not be parsed'));
}
}
$event->setData($identifier);
}
}
关于php - Symfony 2 - 在 preSubmit 事件订阅者上向表单元素添加错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32012510/