2012-11-13 93 views
24

我有我的所有視圖使用的佈局,我需要從控制器分配一個變量到這個佈局,如果我在控制器上使用這種方法它不起作用:Zend Framework 2 - 佈局和變量

public function indexAction() 
{ 
    return new ViewModel(array(
     'testvar' => 'bla', 
    )); 
} 

任何人都可以幫助我嗎?

感謝

+0

它會工作,你嘗試如何訪問「的testvar」? – Sam

+0

我使用$ testvar,但我忘了說佈局在文件夾Application/view/layout中,而我的控制器在另一個模塊中..也許這是問題..我認爲應用程序中的佈局可以在任何地方使用。 – Juck

+2

啊,你想在layout.phtml中使用var而不是在你的action view-scripts中? – Sam

回答

39

羅布·艾倫發佈了一個great article有關如何訪問視圖變量在另一個視圖模型(例如:佈局)

基本上下面的代碼,放置在您layout.phtml內,將滿足您的需求:

<?php 
$children = $this->viewModel()->getCurrent()->getChildren(); 
$child = $children[0]; 
?> 
<!-- some HTML --> 
<?php echo $this->escape($child->myvar);?> 
+4

感謝您的建議,它的工作原理 - 但仍然看起來很複雜:/ * blaming-zf2 * – MonkeyMonkey

+1

@MonkeyMonkey這是因爲這樣的事情通常不是必需的。有更好的方法(比如ViewHelpers/Widgets)比做這種事情更好。但是如果你確實有一個用例,它可以被使用。 – Sam

+0

我可以看到這不應該是必要的,但你會如何建議以正確的方式呢?因爲通過pluginmanager訪問viewhelpers也違背了語義規則,因爲你可以在網絡上閱讀。設置標題描述/標題動作特定 - 或者根據您可能需要的API(facebook)加載一些javascript/dom部件,您只需要執行特定操作就很常見。 –

1

見下

添加視圖變量部分添加在你module.php文件。

你也可以使用視圖助手來做到這一點。

/** 
    * Remember to keep the init() method as lightweight as possible 
    * 
    * @param \Zend\ModuleManager\ModuleManager $moduleManager 
    */ 
    public function init(ModuleManager $moduleManager) 
    {   
     $events = $moduleManager->getEventManager(); 
     $events->attach('loadModules.post', array($this, 'modulesLoaded')); 
     $events->attach('onBootstrap', array($this, 'bootstrap')); 

     $sharedEvents = $events->getSharedManager(); 
     $sharedEvents->attach(__NAMESPACE__, 'bootstrap', array($this, 'bootstrap'), 100); 
     $sharedEvents->attach(__NAMESPACE__, 'bootstrap', array($this, 'initializeView'), 100); 
     $sharedEvents->attach(__NAMESPACE__, 'dispatch', array($this, 'addViewVariables'), 201);   
    } 


/** 
* 
* @param \Zend\Mvc\MvcEvent $e 
*/ 
public function loadConfiguration(MvcEvent $e) 
{   
    $e->getApplication()->getServiceManager() 
      ->get('ControllerPluginManager')->get('AclPlugin') 
      ->checkAcl($e); //Auth/src/Auth/Controller/AclPlugin  
} 

/** 
* 
* @param \Zend\EventManager\EventInterface $e 
*/ 
public function bootstrap(Event $e) { 

    $eventManager = $e->getParam('application')->getEventManager(); 
    //$app->getEventManager()->attach('dispatch', array($this, 'checkAcl'), 100); 
} 

/** 
* pass variables to layout 
* 
* @param \Zend\EventManager\EventInterface $e 
*/ 
public function addViewVariables(Event $e) 
{ 
    $route = $e->getRouteMatch(); 
    $viewModel = $e->getViewModel(); 
    $variables = $viewModel->getVariables(); 
    if (false === isset($variables['controller'])) { 
     $viewModel->setVariable('controller', $route->getParam('controller')); 
    } 
    if (false === isset($variables['action'])) { 
     $viewModel->setVariable('action', $route->getParam('action')); 
    } 

    $viewModel->setVariable('module', strtolower(__NAMESPACE__));   
} 

/** 
* 
* @param \Zend\Mvc\MvcEvent $e 
*/ 
public function initializeView(Event $e) 
{ 

} 

,並在你的佈局,你可以簡單地訪問使用自己的名稱,如$模塊,$行動,$控制這些變量,根據上面的例子

8

你試過:

$this->layout()->testvar = 'bla'; 

使用layout控制器插件可以檢索layout.phtml中使用的ViewModel對象。

3

因爲ZF2 ViewModel是樹結構,佈局實際上是ViewModel的根節點,您的控制器中的ViewModel將作爲佈局的子節點添加。

您可以通過訪問MvcEvent訪問佈局視圖模型,試試這個在您的控制器:

public function indexAction() 
{ 
    $events = $this->getServiceLocator()->get('Application')->getEventManager(); 
    $events->attach(MvcEvent::EVENT_RENDER, array($this, 'setVariableToLayout'), 100); 
} 

public function setVariableToLayout($event) 
{ 
    $viewModel = $this->getEvent()->getViewModel(); 
    $viewModel->setVariables(array(
     'testvar' => 'bla', 
    )); 
} 
64

有三種方式ZF2實現這一目標(在你的控制器):

第一:

$this->layout()->someVariableName = 'Some value for the variable'; 

二:

$this->layout()->setVariable('someVariableName', 'Some value for the variable'); 

第三:

$this->layout()->setVariables(array(
    'someVariableName' => 'Some value for the variable', 
    'anotherVariable' => 'Some value for another variable', 
); 
+2

這是正確的答案。 – Joe

+3

這應該是可以接受的答案。 – dualmon

+0

你將如何訪問它們? –