Symfony2的表單事件 FormEventSubscriber

Form事件是動態處理表單動做的一種方式,在buildForm方法裏添加Subscriber:php

<?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 :dom

<?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監聽事件就完成了
這裏的post

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

還有幾個事件 分別是form的不一樣時期 都是能夠經過監聽來修改它的狀態:ui

<?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一系列的定義裏均可以看到。this

相關文章
相關標籤/搜索