thanks all I have been learning symfony2 recently, and now I can’t understand the EventDispatcher component, and the official documentation is not very clear. . Solve
黄舟2017-05-16 16:46:48
Familiar with jQuery? The event mechanism is always the same:
(1) First define the name of the event
This is like the onclick of js, it is just a recognition. You can define an event name such as: vendor.my_event. For ease of use, you can use an "enumeration" class to record these events:
final class Events
{
const MY_EVENT = 'vendor.my_event';
// 其他event……
}
You can use Events::MY_EVENT in the code instead of writing the string directly. It is not necessary to build this "enumeration" class, but it is recommended:
(2) Define an event class (context definition)
Using jQuery, we generally don’t define event classes ourselves, but in fact this event class also exists (the default one is used). In jQuery’s event callback, the first parameter accepted is the object of the event class, and this object will carry Some contextual stuff like e.target.
Using sf's EventDispatcher, you define your own event class to perform type checking and provide context for callbacks (in layman's terms, what data can be obtained from the event object).
// 这个是sf为你提供的一个基础类
use Symfony\Component\EventDispatcher\Event;
// 你的事件类
class SomeEvent extends Event
{
public function __cosntruct()
{
// 按需定义你的事件类
}
}
(3) Trigger event
You have an event name and an event class, and sf has already equipped you with an event dispatcher. You can use it directly to trigger events:
// 事件上可以携带什么,是通过定义你的事件类来实现的
// 初始化一个事件类,如果你定义了初始化参数,或者事件类上提供了什么方法,就根据需要调用:
$event = new SomeEvent('参数?');
$event->someMethod('你自定义的方法');
// 在controller里取事件分发器
$dispatcher = $this->get('event_dispatcher');
// 将$event,以Events::MY_EVENT事件触发
$dispatcher->dispatch(Events::MY_EVENT, $event);
(4) Define a listener (callback)
// 引入你事件类的实际命名空间
use YourNS\SomeEvent;
class SomeListener
{
public function onMyEvent(SomeEvent $event)
{
// 你从事件上拿到了某个值
$var = $event->getSomeVar();
// 然后可以根据这个值做点什么:
// ...
}
}
(5) Make the callback listen to the corresponding event
You can add callbacks using code:
$listener = new SomeListener(); // 你可以把其他(需要解耦的服务注入到这个listener)
$dispatcher = $this->get('event_dispatcher');
$dispatcher->addListener(Events::MY_EVENT, array($listener, 'onMyEvent'));
You can also use configuration, that is, dependency injection (DIC):
#services.yml
vendor.some_listener:
class: '回调的类名'
#arguments: [ 需要调用的服务 ]
tags:
- { name: kernel.event_listener, event: vendor.my_event, method: onMyEvent }