events - 如何触发附加到 ZF2 中共享事件管理器的事件?

标签 events zend-framework2 eventtrigger event-listener

附加到(本地)事件管理器的事件

public class myClass implements EventManagerAwareInterface {
    ...
    public function __construct(...) {
        ...
        $this->getEventManager()->attach('doEvent', function ($e) {
            $event = $e->getName();
            $params = $e->getParams();
            printf(
                'Handled event "%s", with parameters %s',
                $event,
                json_encode($params)
            );
        });
    }
    ...
    public function getEventManager() {
        if (!$this->eventManager) {
            $this->setEventManager(new EventManager());
        }
        return $this->eventManager;
    }
    public function setEventManager(EventManagerInterface $eventManager) {
        $eventManager->setIdentifiers(array(
            __CLASS__,
            get_class($this),
            'exampleIdentifier',
        ));
        $this->eventManager = $eventManager;
        return $this;
    }
}

可以按如下方式在本地触发:

public class myClass {
    ...
    public function doWhatEver(...) {
        $this->getEventManager()->trigger('doEvent', null, ['foo' => 'bar', 'baz' => 'bat']);
    }
    ...
}

如果我对共享事件管理器的理解正确的话,它是事件和监听器的中央寄存器,捆绑到标识符。每个(本地)事件经理都知道这一点。 (顺便说一句:这个 ZF2 魔法是如何工作的?)每个事件管理器都可以访问 1. 在其中注册的监听器以及 2. 共享事件管理器的“池”。将事件附加到此池类似于附加到事件管理器的常见事件,但需要一个附加参数 - identifier(共享“池”中“监听器包”的键):

this->getEventManager()->getSharedManager()->attach('exampleIdentifier', 'doEvent', function ($e) {
    ...
});

同一类的触发完全相同:

$this->getEventManager()->trigger('doEvent', null, ['foo' => 'bar', 'baz' => 'bat']);

现在我想将触发器调用移至另一个类。但我不明白,如何传递正确的标识符如何从类中触发附加到共享事件管理器的事件,该类的 ServiceManager 具有不同的标识符/标识符设置?

最佳答案

How to trigger an event attached to the Shared Event Manager in ZF2?

尽管有这个名字,SharedEventManager 是 not an event manager ;因此它不能“触发”事件。

这个想法是,您可以将事件监听器附加到通常附加到服务(事件管理器感知)的共享事件管理器。

何苦呢?

共享事件管理器具有以下优点。

  • 新的事件监听器可以附加到可能存在或可能不存在的事件管理器

  • 允许监听器通过使用“标识符”附加到一组可能来自不同来源的事件。

第二点是重要的一点。通过使用事件管理器“标识符”,您可以将事件监听器附加到多个事件管理器/服务。

考虑以下因素

use Zend\EventManager\EventManagerAwareTrait;
use Zend\EventManager\EventManagerAwareInterface;

abstract class AbstractService implements EventManagerAwareInterface
{
    use EventManagerAwareTrait;

    public function __construct()
    {
        $this->getEventManager()->addIdentifiers([
            'my_custom_identifier',
        ]);
    }

    public function doSomething()
    {
        $this->getEventManager()->trigger(__FUNCTION__, ['foo' => 'bar']);
    }
}

class ServiceA extends AbstractService
{}

class ServiceB extends AbstractService
{}

如果没有共享事件管理器,如果我们想要将监听器附加到“doSomething”事件,则需要为每个事件管理器执行此操作。

使用共享管理器,您可以在一次调用中同时定位这两个目标,而无需创建 serviceAserviceB 或复制事件监听器。

use Zend\ModuleManager\Feature\BootstrapListenerInterface;
use Zend\Mvc\MvcEvent;

class Module implements BootstrapListenerInterface
{
    public function onBootstrap(MvcEvent $event)
    {
        $application = $event->getApplication();
        $sharedEventManager = $application->getEventManager()->getSharedManager();

        $sharedEventManager->attach(
            'my_custom_identifier',
            'doSomething',
            function($event) {
                // some work
            }
        );
    }
}

关于events - 如何触发附加到 ZF2 中共享事件管理器的事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30794259/

相关文章:

python - 如何区分音乐和 channel 的endevent?

python - 在pygame中更新一个数字

javascript - 如何绑定(bind)到 "change"事件以便最后调用该函数?

php - 如何在 Zend Framework 2 中打开 PHP 错误报告?

php - ZF2 -\Zend\Db\Adapter\Platform::getQuoteIdentifierSymbol() 函数

jquery - 使用下拉菜单时触发颜色框

c# - 为什么 C# 中的事件要带 (sender, EventArgs)?

forms - 表单集合上的 ZF2 对象绑定(bind)

mysql - 将触发器添加到 Magento 表中以更新数量

android - 以编程方式触发ontouch事件