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

时间:2012-09-28 07:16:46

标签: symfony symfony-forms

使用Symfony中的文本字段类型,有一个trim option。我非常确定trim()类是由Form\Extension\Core\EventListener\TrimListener类进行的。它是PRE_BIND事件的监听者并且调用:

$event->setData(trim($event->getData()));

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

$builder->add('last_name', 'text', array(
    'label'           => 'Last name',
    'normlize_spaces' => true
));

如何为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');
    }
}

1 个答案:

答案 0 :(得分: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());
         }
     }
 }

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

的类。

了解它在此处的声明:https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml

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

How to Override any Part of a Bundle

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

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