将 ZF2 迁移到 ZF3:如何调整导航视图?

Migrating ZF2 to ZF3: How to adapt navigation view?

在我的 ZF2 应用程序中,我有一个导航视图脚本:

$routeMatch = $this->getHelperPluginManager()
    ->getServiceLocator()
    ->get('Application')
    ->getMvcEvent()
    ->getRouteMatch();
$currentRoute = $routeMatch instanceof \Zend\Mvc\Router\RouteMatch ? $routeMatch->getMatchedRouteName() : null;
?>
<?php foreach ($this->container as $page) : ?>
<li <?php echo $currentRoute == $page->getRoute() ? ' class="active"' : null;?>>
    <?php echo $this->navigation()->menu()->htmlify($page, true, false) . PHP_EOL; ?>
</li>
<?php endforeach; ?>

由于 getServiceLocator() 现已弃用,我需要另一种方法来将有关当前路线的信息获取到导航视图脚本中。

此视图脚本被设置为部分并在 layout.phtml:

中调用
echo $this->navigation('navigation')->menu()->setPartial('navigation/default'); 

所以我有了通过模板变量传递需求信息的想法。我在 Module#onDispatch(...):

创建了一个
public function onDispatch(MvcEvent $mvcEvent)
{
    $viewModel = $mvcEvent->getApplication()->getMvcEvent()->getViewModel();
    $routeMatch = $mvcEvent->getRouteMatch();
    $viewModel->currentRoute = $routeMatch instanceof RouteMatch
        ? $routeMatch->getMatchedRouteName() : null
    ;
}

现在我可以在 layout.phtml 中访问它了。但是我找不到将它传递到导航视图脚本的方法,因为 Zend\View\Helper\Navigation\Menu#setPartial(...)` 不接受任何变量参数。

Zend Framework 3中如何将变量(尤其是当前路径的信息)传递到导航视图中?

最简单的方法是使用 DefaultNavigationFactory

假设我们有如下一些路线

'router' => [
    'routes' => [
        'world' => [
            'type'    => Literal::class,
            'options' => [
                'route'    => '/world',
                'defaults' => [
                    'controller' => Controller\IndexController::class,
                    'action'     => 'index',
                ],
            ],
            'may_terminate' => true,
            'child_routes' => [
                'country' => [
                    'type' => Literal::class,
                    'options' => [
                        'route' => '/country',
                        'defaults' => [
                            'controller' => Controller\WorldController::class,
                            'action' => 'country',
                        ],
                    ],
                ],
            ],
        ],
    ],
],

现在我们将在顶级键 navigation 下定义我们的导航配置并启用 zend 导航。您可以将此代码放入您的 config/autoload/global.php

根据上述路线配置,我们的导航配置将如下所示

// configure the navigation
'navigation' => [
    'default' => [
        [
            'label' => 'Home',
            'route' => 'home',
        ],
        [
            'label' => 'World',
            'route' => 'world', // this should be the route name not route pattern like '/world'
            'pages' => [
                [
                    'label' => 'Country',
                    'route' => 'world/country',
                ],
            ],
        ],
    ],
],

// Register the navigation
'service_manager' => [
    'factories' => [
        'navigation' => Zend\Navigation\Service\DefaultNavigationFactory::class,
    ],
],

现在我们可以使用上面配置中的顶部键 navigation 将导航视图助手调用到视图脚本中。见下文

<div class="collapse navbar-collapse">
    <?php 
        echo $this->navigation('navigation')
            ->menu()
            ->setUlClass('nav navbar-nav')
            ->renderMenu(); 
        ?>
</div>

就是这样!

下面展示了如何通过导航助手的setter方法限制到用户的路由和设置ACL对象或用户角色对象。这里 $this->loggedInUser$this->acl$this->userRole 已被注入到视图脚本中,因此

<div class="collapse navbar-collapse" id="main-menu">

    <?php if ($this->loggedInUser !== null) : ?>
        <?php $this->navigation('navigation')
                ->findBy('route', 'hello')
                ->setParams(array('username' => $this->loggedInUser->getUsername())); ?> // If you need to pass any params

        <?php $this->navigation('navigation')
                ->findBy('route', 'world'); ?>

    <?php endif; ?>

    <?php 
        echo $this->navigation('navigation')
            ->menu()
            ->setUlClass('nav navbar-nav')
            ->setAcl($this->acl) // ACL object
            ->setRole($this->userRole) // Role Object
            ->renderMenu(); 
    ?>

</div>

希望对您有所帮助!