magento2 [必备技巧]之 Events的使用

事件和观察者 ( 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区域允许观察者在所有区域(adminhtmlcrontabfrontendgraphqlwebapi_restwebapi_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>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容