Layout Zend Framework 2-布局和变量

Layout Zend Framework 2-布局和变量,layout,zend-framework2,Layout,Zend Framework2,我的所有视图都使用了一个布局,我需要从控制器向该布局分配一个变量,如果我在控制器上使用此方法,则该方法无效: public function indexAction() { return new ViewModel( array( 'testvar' => 'bla', )); } 有人能帮我吗 感谢Rob Allen发布了一篇关于如何在另一个视图模型(例如:布局)中访问视图变量的文章 基本上,放置在layout.phtml中的以下代码将符合您的需要: &

我的所有视图都使用了一个布局,我需要从控制器向该布局分配一个变量,如果我在控制器上使用此方法,则该方法无效:

public function indexAction()
{
    return new ViewModel( array(
        'testvar' => 'bla',
    ));
}
有人能帮我吗

感谢

Rob Allen发布了一篇关于如何在另一个视图模型(例如:布局)中访问视图变量的文章

基本上,放置在layout.phtml中的以下代码将符合您的需要:

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

请参见下面的添加视图变量部分

将其添加到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) 
{

}
在您的布局中,您只需使用$module、$action、$controller等名称访问这些变量,根据上述示例

您是否尝试过:

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

使用
layout
控制器插件,可以检索
layout.phtml
中使用的ViewModel对象

由于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',
    ));
}

在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',
);

如果您想全局地将值传递给布局,那么您可以参考以下内容:

这会起作用,您如何尝试访问“testvar”?我使用$testvar,但我忘了说布局在文件夹Application/view/layout中,而我的控制器在另一个模块中。。也许这就是问题所在。。我认为应用程序中的布局可以在任何地方使用。啊,你想在layout.phtml中使用var,而不是在动作视图脚本中使用吗?谢谢你的建议,它可以工作,但看起来仍然很复杂-zf2@MonkeyMonkey这是因为像这样的事情通常是不必要的。有更好的方法(比如ViewHelpers/widget),而不是做这种事情。但是如果你真的有一个用例的话,它是可以使用的。我可以看出这不应该是必要的,但是你会如何建议用正确的方法来做呢?因为通过pluginmanager访问ViewHelper也违反了语义规则,因为您可以在web上阅读。设置特定于标题描述/标题操作的标题是很常见的,或者根据您可能需要的API(facebook)加载一些javascript/dom部分,这些API可能只用于特定操作。有一个headTitle()ViewHelper-您能否进一步解释您的“违反语义规则,因为您可以在web上阅读”?这句话似乎很“错误”,呵呵。我的意思是,不建议在控制器中访问ViewHelper,也认为这样做是错误的。但正如你所说,head*家族是为了改变标题和meta的,出于SEO原因或其他原因,偶然改变标题和描述是很正常的。。因此,如果访问控制器中的ViewHelper不符合我所说的“语义正确”,您将如何做到这一点?然后您将如何访问它们?@FrancescoD.M。只需在布局文件中按名称访问它们,就像任何其他变量一样,如
echo$someVariableName