首页  >  问答  >  正文

symfony - EventDispatcher组件

thanks all 最近一直在学symfony2,现在对于EventDispatcher组件理解不了,官方文档不是很明白。。求解

ringa_leeringa_lee2734 天前311

全部回复(1)我来回复

  • 黄舟

    黄舟2017-05-16 16:46:48

    对jQuery熟悉?事件机制总是差不多的:

    (一)先定义event的名字

    这个就好比js的onclick,是一个识别而已,你可以定义个事件名字如:vendor.my_event,为了方便使用,你可以用一个“枚举”类来记录这些event:

    final class Events
    {
        const MY_EVENT = 'vendor.my_event';
        // 其他event……
    }
    

    代码里就可以用Events::MY_EVENT来代替直接写那个字符串,建这个“枚举”类不是必须,但推荐这么做:

    1. 万一写错了,会直接报错,方便调试
    2. 集中起来,方便维护(不然忘了到底有哪些事件了)

    (二)定义一个事件类(上下文定义)

    用jQuery我们一般不会自己定义事件类,但其实这个事件类也是存在的(用的默认的),在jQuery的事件回调里,接受的第一个参数就是事件类的对象,这个对象会携带一些上下文的东西,如e.target。

    用sf的EventDispatcher,你通过定义自己的事件类,来进行类型检查,和提供回调时的上下文(通俗的说,就是可以从事件对象上取到什么数据)。

    // 这个是sf为你提供的一个基础类
    use Symfony\Component\EventDispatcher\Event;
    
    // 你的事件类
    class SomeEvent extends Event
    {
        public function __cosntruct()
        {
            // 按需定义你的事件类
        }
    }
    
    

    (三)触发事件

    你有一个事件名了,和一个事件类了,而sf已经给你配好了一个事件分发器,你可以直接使用它来触发事件:

    // 事件上可以携带什么,是通过定义你的事件类来实现的
    // 初始化一个事件类,如果你定义了初始化参数,或者事件类上提供了什么方法,就根据需要调用:
    $event = new SomeEvent('参数?');
    $event->someMethod('你自定义的方法');
    
    // 在controller里取事件分发器
    $dispatcher = $this->get('event_dispatcher');
    
    // 将$event,以Events::MY_EVENT事件触发
    $dispatcher->dispatch(Events::MY_EVENT, $event); 
    

    (四)定义一个监听(回调)

    // 引入你事件类的实际命名空间
    use YourNS\SomeEvent;
    
    class SomeListener
    {
        public function onMyEvent(SomeEvent $event)
        {
            // 你从事件上拿到了某个值
            $var = $event->getSomeVar();
            // 然后可以根据这个值做点什么:
            // ...
        }
    }
    

    (五)使回调监听相应事件

    你可以用代码的方式来添加回调:

    $listener = new SomeListener(); // 你可以把其他(需要解耦的服务注入到这个listener)
    
    $dispatcher = $this->get('event_dispatcher');
    $dispatcher->addListener(Events::MY_EVENT, array($listener, 'onMyEvent'));
    

    你也可以用配置的方式,也就是用依赖注入(DIC)来做:

    #services.yml
    vendor.some_listener:
        class: '回调的类名'
        #arguments: [ 需要调用的服务 ]
        tags:
            - { name: kernel.event_listener, event: vendor.my_event, method: onMyEvent }
    
    

    回复
    0
  • 取消回复