2014-10-02 87 views
0

我想根據我的路線改變佈局,在這裏我做了什麼至今:ZF2改變佈局

<?php namespace Application\Listener; 

use Zend\EventManager\AbstractListenerAggregate; 
use Zend\EventManager\EventManagerInterface; 
use Zend\Mvc\MvcEvent; 
use Zend\View\Model\ModelInterface as Model; 

class LayoutListener extends AbstractListenerAggregate 
{ 
    /** 
    * Attach one or more listeners 
    * Implementors may add an optional $priority argument; the EventManager 
    * implementation will pass this to the aggregate. 
    * @param EventManagerInterface $events 
    * @return void 
    */ 
    public function attach(EventManagerInterface $events) 
    { 
     $sharedEvents = $events->getSharedManager(); 
     $this->listeners[] = $sharedEvents->attach(
      'Zend\Mvc\Controller\AbstractController', 
      MvcEvent::EVENT_DISPATCH, 
      array($this, 'handleLayouts'), 
      -99); 
    } 

    public function handleLayouts(MvcEvent $event) 
    { 
     $viewModel = $event->getViewModel(); 
     if (!$viewModel instanceof Model) { 
      return; 
     } 

     $routeMatch = $event->getRouteMatch(); 
     $resolver = $event->getApplication() 
      ->getServiceManager() 
      ->get('Zend\View\Resolver\TemplatePathStack'); 

     if ('Application\Controller\Index' !== $routeMatch->getParam('controller')) { 
      return; 
     } 

     switch ($routeMatch->getParam('action')) { 
      case 'index': 
       $template = 'layout/layout'; 
       break; 
      case 'home': 
       $template = 'layout/home'; 
       break; 
      default: 
       $template = null; 
       break; 
     } 

     /** 
     * 
     * Don't know why, but to set a template must use $event->getViewModel() 
     * and for terminal must use $event->getResult(), otherwise it won't works 
     * 
     */ 

     // if template is resolvable, use it, otherwise go terminal 
     if ($template && $resolver->resolve($template)) { 
      $viewModel->setTemplate($template); 
     } else { 
      if ($event->getResult() instanceof Model) { 
       $event->getResult()->setTerminal(true); 
       $viewModel->setTerminal(true); 
      } 
     } 
    } 
} 

Module.php

public function onBootstrap(MvcEvent $e) 
{ 
    $translator = $e->getApplication()->getServiceManager()->get('translator'); 
    $translator->setLocale(\Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE'])) 
     ->setFallbackLocale('en_US'); 

    $eventManager = $e->getApplication()->getEventManager(); 
    $eventManager->attachAggregate(new LayoutListener()); 

    $moduleRouteListener = new ModuleRouteListener(); 
    $moduleRouteListener->attach($eventManager); 
} 

有一個事情我不明白,如果我想改變佈局,我必須用

  • $event->getViewModel()->setTemplate($template);

否則將無法正常工作,如果我想設置視圖模型終端,我必須用

  • $event->getResult()->setTerminal(true);

否則將無法正常工作,能有人解釋我爲什麼?

我試圖實現它的以下內容:我有一個索引模板,用於初始化加載任何其他路由內容的iFrame,因此在索引布局中,我設置了菜單和其他任何頁面使用索引/索引時不需要佈局。

現在我想有一個自定義佈局(自定義顯示),因此,根據路線上的子頁面,我設置一個新的佈局到視圖模型。

回答

1

您可以添加兒童觀看您的視圖模型(如果你在一個控制器) - 如果你做出自己的控制器爲您的子視圖(或子頁面):

$view = new ViewModel(array(
    // parameters 
)); 

$view->addChild($this->forward()->dispatch('SubpageController', array(
    'action' => 'index', 
)), 'contentOfSubpage'); 

return $view; 
模板

,你可以訪問SubpageController的內容是這樣的:

<?php echo $contentOfSubpage; ?> 

至少,這就是如何結合多個控制器,

+0

感謝提示,因此不同的佈局,但它並沒有真正回答我的追求離子 – kitensei 2014-10-03 13:03:36