事件和观察者 ( Events and observers)
概述
使用Events and observers是扩展 Magento 功能的主要方式之一。Magento 2 中的事件和观察者实现基于发布-订阅模式。使用事件和观察者,您可以运行自定义代码来响应特定的 Magento事件甚至自定义事件。
活动
当触发某些操作时,事件由模块分派。除了它自己的事件之外,Magento 还允许您创建可以在您的代码中调度的自己的事件。当一个事件被调度时,它可以将数据传递给任何被配置为观察该事件的观察者。
调度事件
可以使用Magento\Framework\Event\ManagerInterface
该类来分派事件。这个类可以通过在你的构造函数中定义依赖来通过依赖注入获得。
要分派事件,请调用dispatch
事件管理器类的函数,并为它提供您要分派的事件的名称以及您希望提供给观察者的数据数组。
以下示例向您展示了如何分派带有和不带有数据数组的事件。
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MyCompany\MyModule;
use Magento\Framework\Event\ManagerInterface as EventManager;
class MyClass
{
/**
* @var EventManager
*/
private $eventManager;
/*
* @param EventManager $eventManager
*/
public function __construct(EventManager $eventManager)
{
$this->eventManager = $eventManager;
}
public function something()
{
$eventData = null;
// Code...
$this->eventManager->dispatch('my_module_event_before');
// More code that sets $eventData...
$this->eventManager->dispatch('my_module_event_after', ['myEventData' => $eventData]);
}
}
创建新事件
dispatch
调用函数时,只需将唯一的事件名称传递给事件管理器,即可分派自定义事件。您的唯一事件名称在您的模块events.xml
文件中引用,您可以在该文件中指定哪些观察者将对该事件做出反应。
您可以通过如下my_module_event_after
声明文件来使自定义事件可订阅:MyCompany/MyModule/etc/events.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="my_module_event_after">
<observer name="my_module_event_after_observer" instance="MyCompany\MyModule\Observer\MyEvent"/>
</event>
</config>
活动区域
通常,events.xml
文件的位置将在<module-root>/etc
目录下。与此处事件关联的观察者将在全球范围内监视这些事件。该events.xml
文件还可以在<module-root>/etc/frontend
和<module-root>/etc/adminhtml
目录下定义,以将观察者配置为仅监视那些特定区域中的事件。
在适当的区域声明观察者。该global
区域允许观察者在所有区域(adminhtml
、crontab
、frontend
、graphql
、webapi_rest
、webapi_soap
)中奔跑。
区域 | 文件位置 |
---|---|
global |
<module-dir>/etc/events.xml |
adminhtml |
<module-dir>/etc/adminhtml/events.xml |
crontab |
<module-dir>/etc/crontab/events.xml |
frontend |
<module-dir>/etc/frontend/events.xml |
graphql |
<module-dir>/etc/graphql/events.xml |
webapi_rest |
<module-dir>/etc/webapi_rest/events.xml |
webapi_soap |
<module-dir>/etc/webapi_soap/events.xml |
观察员
观察者是某种类型的 Magento 类,可以影响一般行为、性能或更改业务逻辑。每当事件管理器调度它们配置为观察的事件时,就会执行观察者。
创建观察者
要创建观察者,您必须将类文件放在您的<module-root>/Observer
目录下。你的观察者类应该实现Magento\Framework\Event\ObserverInterface
并定义它的execute
功能。
下面是一个基本的观察者类结构的例子:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MyCompany\MyModule\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
class MyObserver implements ObserverInterface
{
public function __construct()
{
// Observer initialization code...
// You can use dependency injection to get any class this observer may need.
}
public function execute(Observer $observer)
{
// Observer execution code...
}
}
观察者更强大的特性之一是它们能够在事件被调度时使用传递给事件的参数。下面是一个观察者在分派事件时获取传入数据的示例。
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MyCompany\MyModule\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
class AnotherObserver implements ObserverInterface
{
public function __construct()
{
// Observer initialization code...
// You can use dependency injection to get any class this observer may need.
}
public function execute(Observer $observer)
{
$myEventData = $observer->getData('myEventData');
// Additional observer execution code...
}
}
订阅事件
可以配置观察者来观察events.xml
文件中的某些事件。
observer
xml元素具有以下属性:
-
name
(必需)- 事件定义的观察者的名称。 -
instance
(必需) - 观察者的完全限定类名。 -
disabled
- 确定此观察者是否处于活动状态。默认值为假。 -
shared
- 确定班级的生活方式。默认为true
。
观察者名称必须是唯一的,否则将发生覆盖。
下面是一个如何分配观察者来观察某些事件的例子:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="my_module_event_before">
<observer name="myObserverName" instance="MyCompany\MyModule\Observer\MyObserver" />
</event>
<event name="my_module_event_after">
<observer name="myObserverName" instance="MyCompany\MyModule\Observer\AnotherObserver" />
</event>
</config>
在前面的示例中,我们将观察者分配给自MyObserver
定义事件my_module_event_before
和.AnotherObserver``my_module_event_after
每个事件定义的观察者名称必须是唯一的。这意味着在同一个事件定义中不能有两个同名的观察者。在这个例子中,两个观察者都有名字myObserverName
。这是可以接受的,因为这些观察者中的每一个都属于不同的事件定义。
如果您声明一个观察者,其名称已在同一事件中使用,Magento 会将这些声明节点合并为一个观察者声明,遵守app/etc/config.php
文件中定义的模块加载顺序。这在禁用另一个模块中声明的观察者时很有用。
禁用观察者
如果您不想让它们运行,可以禁用现有的观察者。如果您想更改其逻辑而不是覆盖它,禁用观察器是一个很好的做法。下面是如何禁用先前创建的观察者的示例。
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="my_module_event_before">
<observer name="myObserverName" disabled="true" />
</event>
</config>
推荐阅读
</main>