表单事件监听器(如TrimListener)如何"绑定"到Symfony中的表单选项?

gre*_*emo 2 symfony-forms symfony

使用Symfony中的文本字段类型,有一个修剪选项.我很确定该trim()操作是由Form\Extension\Core\EventListener\TrimListener班级进行的.它是该PRE_BIND事件的监听者并致电:

$event->setData(trim($event->getData()));
Run Code Online (Sandbox Code Playgroud)

我想提供自己的"normalize_spaces"选择:

$builder->add('last_name', 'text', array(
    'label'           => 'Last name',
    'normlize_spaces' => true
));
Run Code Online (Sandbox Code Playgroud)

我怎样才能提供这个选项NormalizeSpacesListener

class NormalizeSpacesListener implements EventSubscriberInterface
{
    public function preBind(FormEvent $event)
    {
        $data = $event->getData();

        if (is_string($data)) {
            $event->setData(preg_replace('/[ ]{2,}/', ' ', $data));
        }
    }

    public static function getSubscribedEvents()
    {
        return array(FormEvents::PRE_BIND => 'preBind');
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

我想你可能会覆盖Symfony核心FormType类,尤其是buildForm方法:https: //github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/FormType.php

并为该选项添加测试,就像他们为trim选项一样.就像是:

Class MyFormType Extends FormType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         parent::buildForm($builder, $options);

         if ($options['normalize_spaces']) {
             $builder->addEventSubscriber(new NormalizeSpacesListener());
         }
     }
 }
Run Code Online (Sandbox Code Playgroud)

要覆盖该类并让系统使用它而不是默认的核心类,您可以使用服务容器并更改服务form.type.form的类.

看看它在这里如何声明:https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml

并阅读本文以了解如何实际告诉服务容器使用您自己的类而不是默认类:

如何覆盖Bundle的任何部分

注意:我就是这样做的,但我还没有测试过我刚写的内容

另一种选择是将监听器附加到您构建的每个表单,而不是将其作为默认选项.我认为这也会奏效.