magento2设计模式应用之事件和观察者

7天成为Magento系统架构师,现在开始学习Magento全栈开发!

《Magento2.X企业级开发实战》

事件和观察者

概述

使用事件和观察者是扩展 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_beforeAnotherObservermy_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>
如无特殊说明或标注,任何个人或组织,复制、转载、采集本站内容请注明:
本文来源于:【Magento中文网】,并添加本文地址链接。
如未按上述操作复制或转载,本站有权追究法律责任。
若本站内容侵犯了原著者的合法权益,可联系我们进行处理。