Zend Framework 2:导航

Ere*_*ite 4 php zend-framework2

在我的控制器中,我创建了Navigation对象并将其传递给视图

$navigation = new \Zend\Navigation\Navigation(array(
    array(
            'label' => 'Album',
            'controller' => 'album',
            'action' => 'index',
            'route' => 'album',
        ),
    ));
Run Code Online (Sandbox Code Playgroud)

试图使用它

<?php echo $this->navigation($this->navigation)->menu() ?>
Run Code Online (Sandbox Code Playgroud)

并得到错误:

致命错误:Zend\Navigation\Exception\DomainException:Zend\Navigation\Page\Mvc :: getHref无法执行,因为没有Zend\Mvc\Router\RouteStackInterface实例在第471行的Zend\View\Helper\Navigation\AbstractHelper.php中编写

但是我在布局中使用的导航,因此它写在这里:http://adam.lundrigan.ca/2012/07/quick-and-dirty-zf2-zend-navigation/工作.我的错是什么?

谢谢.

Jur*_*man 9

问题是缺少路由器(或者更确切地说是a Zend\Mvc\Router\RouteStackInterface).路由堆栈是路由的集合,可以使用路由名称将其转换为URL.基本上它接受路由名称并为您创建一个URL:

$url = $routeStack->assemble('my/route');
Run Code Online (Sandbox Code Playgroud)

这也发生在MVC页面内部Zend\Navigation.该页面有一个route参数,当有可用的路由器时,该页面会组装它自己的URL(或者Zend\Navigation说是一个href).如果您不提供路由器,则无法组装路由,从而引发异常.

您必须在导航的每个页面中注入路由器:

$navigation = new Navigation($config);
$router     = $serviceLocator->get('router');

function injectRouter($navigation, $router) {
  foreach ($navigation->getPages() as $page) {
    if ($page instanceof MvcPage) {
      $page->setRouter($router);
    }

    if ($page->hasPages()) {
      injectRouter($page, $router);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,它是一个递归函数,将路由器注入每个页面.乏味!因此,有一家工厂为您做这件事.实现这一目标有四个简单的步骤.

第一步

首先将导航配置放入模块配置中.正如您有default导航一样,您可以创建第二个导航secondary.

'navigation' => array(
    'secondary' => array(
        'page-1' => array(
            'label' => 'First page',
            'route' => 'route-1'
        ),
        'page-2' => array(
            'label' => 'Second page',
            'route' => 'route-2'
        ),
    ),
),
Run Code Online (Sandbox Code Playgroud)

您有到第一页(route-1)和第二页(route-2)的路线.

第二步

工厂会将其转换为导航对象结构,您需要先为其创建一个类.SecondaryNavigationFactory.php在MyModule/Navigation/Service目录中创建一个文件.

namespace MyModule\Navigation\Service;

use Zend\Navigation\Service\DefaultNavigationFactory;

class SecondaryNavigationFactory extends DefaultNavigationFactory
{
    protected function getName()
    {
        return 'secondary';
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅我在secondary此处输入的名称,该名称与导航键相同.

第三步

您必须将此工厂注册到服务经理.然后工厂可以完成它的工作并将配置文件转换为Zend\Navigation对象.您可以在module.config.php中执行此操作:

'service_manager' => array(
    'factories' => array(
        'secondary_navigation' => 'MyModule\Navigation\Service\SecondaryNavigationFactory'
    ),
)
Run Code Online (Sandbox Code Playgroud)

看我在secondary_navigation这里做了一个服务,Zend\Navigation然后工厂将返回一个实例.如果你现在这样做,$sm->get('secondary_navigation')你会看到这是一个Zend\Navigation\Navigation对象.

第四步

告诉视图助手使用此导航而不是默认导航.导航视图助手接受"导航"参数,您可以在其中说明所需的导航.在这种情况下,服务管理器有一个服务secondary_navigation,这是我们需要的服务.

<?= $this->navigation('secondary_navigation')->menu() ?>
Run Code Online (Sandbox Code Playgroud)

现在,您将secondary在此视图助手中使用导航.

披露:这个答案与我在这个问题上给出的答案相同:https://stackoverflow.com/a/12973806/434223


And*_*den 2

顺便提一句。您不需要定义controller并且action如果您定义 a route,仅当您的路线是通用的并且控制器/操作是可变段时。