Form事件是动态处理表单动作的一种方式,在buildForm方法里添加Subscriber:

<?php

namespace Demo\AdminBundle\Form\Type;

use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;

class RegistrationFormType extends BaseType
{

    private $doctrine;

    public function __construct( $class ,  \Doctrine\Bundle\DoctrineBundle\Registry $doctrine)
    {
        parent::__construct( $class);
        $this->doctrine = $doctrine;
    }

    public function buildForm( FormBuilderInterface $builder , array $option )
    {
        parent::buildForm($builder, $option);

        $builder->add('name')
                ;
        //这里传递FormFactory到监听器里 用来修改表单
        $subscriber = new \Mc\AdminBundle\EventListener\FormSetDataListener($builder->getFormFactory());
        //添加subscriber
        $builder->addEventSubscriber( $subscriber);

    }
   ...

然后写一下Subscriber :

<?php
namespace Demo\AdminBundle\EventListener;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;


class FormSetDataListener implements EventSubscriberInterface
{

    private $factory;

    public function __construct( FormFactoryInterface $factory)
    {
        $this->factory = $factory;
    }

    public static function getSubscribedEvents()
    {
        return array( FormEvents::POST_SET_DATA => 'postSetData');
    }

    public function postSetData( FormEvent $event )
    {   
        $form = $event->getForm();
        $data = $event->getData();

        if( null == $data)
        {
            return ;
        }
        //这里我的操作是移除原先的密码框 然后手动给它填充数据 data的数据是从另外一个表单传递到这个表单来的 (基于FOSUserBundle做的一个分步注册的功能 俗称form wizard) 这个数据来源直接在FormFactory获取就好了 
        //这样等于在这里重建了一下form
        $form->remove('plainPassword');

        $form->add('plainPassword', 'repeated', array(
                'data' => $data->getPassword() , 
                'type' => 'text',
                'options' => array('translation_domain' => 'FOSUserBundle'),
                'first_options' => array('label' => 'form.password'),
                'second_options' => array('label' => 'form.password_confirmation'),
                'invalid_message' => 'fos_user.password.mismatch',
            )
        );

    }
}

到这里一个form监听事件就完成了
这里的

    public static function getSubscribedEvents()
    {
        return array( FormEvents::POST_SET_DATA => 'postSetData');
    }

还有几个事件 分别是form的不同时期 都是可以通过监听来修改它的状态:

<?php
/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Form;

/**
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
final class FormEvents
{

    const PRE_SUBMIT = 'form.pre_bind';

    const SUBMIT = 'form.bind';

    const POST_SUBMIT = 'form.post_bind';

    const PRE_SET_DATA = 'form.pre_set_data';

    const POST_SET_DATA = 'form.post_set_data';

    /**
     * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use
     *             {@link PRE_SUBMIT} instead.
     */
    const PRE_BIND = 'form.pre_bind';

    /**
     * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use
     *             {@link SUBMIT} instead.
     */
    const BIND = 'form.bind';

    /**
     * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use
     *             {@link POST_SUBMIT} instead.
     */
    const POST_BIND = 'form.post_bind';

    private function __construct()
    {
    }
}

至于每个事件的先后顺序 可以在form一系列的定义里都可以看到。


mot
1.2k 声望16 粉丝

引用和评论

0 条评论