Zend framework2 ZF3-事件管理器和调度事件

Zend framework2 ZF3-事件管理器和调度事件,zend-framework2,zend-framework3,Zend Framework2,Zend Framework3,在旧的ZF2应用程序中,如果匹配的路由以admin开头,我会更改调度侦听器中的布局。现在,我启动了一个新项目,希望使用ZF3组件,但事件管理器确实有一些更改,我得到以下例外: 未捕获的TypeError:传递给Zend\EventManager\EventManager::attach()的参数2必须是可调用的,未指定任何参数 我真的不知道如何在ZF3中处理这个问题。以下是我在ZF2应用程序中更改布局的相关源代码: Module.php namespace Admin; use Zend\Ev

在旧的ZF2应用程序中,如果匹配的路由以
admin
开头,我会更改调度侦听器中的布局。现在,我启动了一个新项目,希望使用ZF3组件,但事件管理器确实有一些更改,我得到以下例外:

未捕获的TypeError:传递给Zend\EventManager\EventManager::attach()的参数2必须是可调用的,未指定任何参数

我真的不知道如何在ZF3中处理这个问题。以下是我在ZF2应用程序中更改布局的相关源代码:

Module.php

namespace Admin;

use Zend\EventManager\EventInterface;
use Zend\ModuleManager\Feature\BootstrapListenerInterface;

class Module implements BootstrapListenerInterface {

    public function onBootstrap(EventInterface $event) {
        $application = $event->getApplication();
        $eventManager = $application->getEventManager();
        $serviceManager = $application->getServiceManager();

        $eventManager->attach($serviceManager->get('Admin\Listener\Dispatch'));
    }

}
namespace Admin\Listener;

use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;

class DispatchListener extends AbstractListenerAggregate {

    public function attach(EventManagerInterface $eventManager) {
        $this->listeners[] = $eventManager->attach(
            MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch'), 100
        );
    }

    public function onDispatch(EventInterface $event) {
        $matchedRouteName = $event->getRouteMatch()->getMatchedRouteName();

        if (strpos($matchedRouteName, 'admin') === 0) {
            $event->getViewModel()->setTemplate('layout/admin');
        }
    }

}
DispatchListener.php

namespace Admin;

use Zend\EventManager\EventInterface;
use Zend\ModuleManager\Feature\BootstrapListenerInterface;

class Module implements BootstrapListenerInterface {

    public function onBootstrap(EventInterface $event) {
        $application = $event->getApplication();
        $eventManager = $application->getEventManager();
        $serviceManager = $application->getServiceManager();

        $eventManager->attach($serviceManager->get('Admin\Listener\Dispatch'));
    }

}
namespace Admin\Listener;

use Zend\EventManager\AbstractListenerAggregate;
use Zend\EventManager\EventInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;

class DispatchListener extends AbstractListenerAggregate {

    public function attach(EventManagerInterface $eventManager) {
        $this->listeners[] = $eventManager->attach(
            MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch'), 100
        );
    }

    public function onDispatch(EventInterface $event) {
        $matchedRouteName = $event->getRouteMatch()->getMatchedRouteName();

        if (strpos($matchedRouteName, 'admin') === 0) {
            $event->getViewModel()->setTemplate('layout/admin');
        }
    }

}

zf3更侧重于解耦组件,似乎已删除聚合以附加事件。请参见api文档

简言之,附加信息说

attach($eventName, callable $listener, $priority = 1) : callable
我希望,由于您没有指定eventName,因此会收到错误消息

更新:

请参阅event manager从v2到v3的迁移指南链接


在ZF3中,您可以通过以下简单方式更改控制器的布局:

<?php
namespace YourCompanyModule;

use Zend\ModuleManager\ModuleManager;
use Zend\Mvc\MvcEvent;

class Module
{
    // The "init" method is called on application start-up and 
    // allows to register an event listener.
    public function init(ModuleManager $manager)
    {
        // Get event manager.
        $eventManager = $manager->getEventManager();
        $sharedEventManager = $eventManager->getSharedManager();
        // Register the event listener method. 
        $sharedEventManager->attach(__NAMESPACE__, 'dispatch', 
                                    [$this, 'onDispatch'], 100);
    }

    // Event listener method.
    public function onDispatch(MvcEvent $event)
    {
        // Get controller to which the HTTP request was dispatched.
        $controller = $event->getTarget();
        // Get fully qualified class name of the controller.
        $controllerClass = get_class($controller);
        // Get module name of the controller.
        $moduleNamespace = substr($controllerClass, 0, strpos($controllerClass, '\\'));

        // Switch layout only for controllers belonging to our module.
        if ($moduleNamespace == __NAMESPACE__) {
            $viewModel = $event->getViewModel();
            $viewModel->setTemplate('layout/layout2');  
        }        
    }

    // ...
}

尝试将第二个参数添加到:public function attach(EventManagerInterface$eventManager,$priodity=1){…}聚合仍然存在。请参阅文档:好的,我将Module.php中的侦听器附件更改为以下内容,现在一切正常。非常感谢<代码>$eventManager->attach(MvcEvent::EVENT_DISPATCH,[$serviceManager->get(Listener\DispatchListener::class),'onDispatch'])