Dom*_*ann 6 php zend-framework2
如何收听特定控制器的调度事件?目前我做了以下事情:
Module.php
public function onBootstrap(EventInterface $event) {
$application = $event->getApplication();
$eventManager = $application->getEventManager();
$serviceManager = $application->getServiceManager();
$eventManager->attach($serviceManager->get('MyListener'));
}
Run Code Online (Sandbox Code Playgroud)
MyListener.php
class MyListener extends AbstractListenerAggregate {
public function attach(EventManagerInterface $eventManager) {
$this->listeners[] = $eventManager->attach(
MvcEvent::EVENT_DISPATCH, function($event) {
$this->setLayout($event);
}, 100
);
}
public function setLayout(EventInterface $event) {
$event->getViewModel()->setTemplate('mylayout');
}
}
Run Code Online (Sandbox Code Playgroud)
这将设置所有控制器调度的布局.现在我只想在应用程序调度特定控制器时设置布局.
像所有模块都有onBootstrap()方法一样,所有扩展AbstractController的控制器都有一个onDispatch()方法.
考虑到您要为单个特定控制器应用不同的布局,您只需执行以下操作:
<?php
namespace MyModule\Controller;
use Zend\Mvc\Controller\AbstractActionController; // Or AbstractRestfulController or your own
use Zend\View\Model\ViewModel; // Or JsonModel or your own
use Zend\Mvc\MvcEvent;
class MyController extends AbstractActionController
{
public function onDispatch(MvcEvent $e)
{
$this -> layout('my-layout'); // The layout name has been declared somewhere in your config
return parent::onDispatch($e); // Get back to the usual dispatch process
}
// ... Your actions
}
Run Code Online (Sandbox Code Playgroud)
您可以为具有特殊布局的每个控制器执行此操作.对于那些不这样做的人,你不需要写任何东西.
如果您经常需要更改布局(例如,您必须处理不是一个控制器而是几个),您可以在module.php中附加一个MvcEvent,以便将布局设置代码放在一个位置.
为了简单起见,我不是在这里使用自定义监听器,但您也可以使用自定义监听器.
<?php
namespace MyModule;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e -> getApplication() -> getEventManager();
$eventManager -> attach(
MvcEvent::EVENT_DISPATCH,
// Add dispatch error event only if you want to change your layout in your error views. A few lines more are required in that case.
// MvcEvent::EVENT_DISPATCH | MvcEvent::EVENT_DISPATCH_ERROR
array($this, 'onDispatch'), // Callback defined as onDispatch() method on $this object
100 // Note that you don't have to set this parameter if you're managing layouts only
);
}
public function onDispatch(MvcEvent $e)
{
$routeMatch = $e -> getRouteMatch();
$routeParams = $routeMatch -> getParams();
switch ($routeParams['__CONTROLLER__']) {
// You may use $routeParams['controller'] if you need to check the Fully Qualified Class Name of your controller
case 'MyController':
$e -> getViewModel() -> setTemplate('my-first-layout');
break;
case 'OtherController':
$e -> getViewModel() -> setTemplate('my-other-layout');
break;
default:
// Ignore
break;
}
}
// Your other module methods...
}
Run Code Online (Sandbox Code Playgroud)
您必须将事件侦听器附加到 SharedEventManager 并侦听“Zend\Stdlib\DispatchableInterface”接口的 MvcEvent::EVENT_DISPATCH。
看一个例子:
$eventManager->getSharedManager()
->attach(
'Zend\Stdlib\DispatchableInterface',
MvcEvent::EVENT_DISPATCH,
$serviceManager->get('MyListener')
);
Run Code Online (Sandbox Code Playgroud)
在监听器中,您可以获取目标控制器的实例,如下所示 $controller = $event->getTarget();
因此,最终,“setLayout”方法可能如下所示:
public function setLayout(MvcEvent $event)
{
$controller = $event->getTarget();
if ($controller instanceof MyController)
{
$event->getViewModel()->setTemplate('mycontroller-layout');
}
}
Run Code Online (Sandbox Code Playgroud)