问题是缺少路由器(或更精确地说,Zend\Mvc\Router\RouteStackInterface
)。 路由堆栈是路由的集合,可以使用路由名称将其转换为URL。 基本上,它接受路由名称并为您创建URL:
$url = $routeStack->assemble('my/route');
这种情况也发生在Zend\Navigation
的MVC页面中。该页面具有一个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);
}
}
}
正如你所看到的,这是一个递归函数,将路由器注入到每个页面中。很繁琐!因此,有一个工厂可以为您完成这项工作。有四个简单的步骤可以实现这一点。
第一步
首先将导航配置放在模块配置中。就像你有一个default
导航一样,你可以创建第二个secondary
导航。
'navigation' => array(
'secondary' => array(
'page-1' => array(
'label' => 'First page',
'route' => 'route-1'
),
'page-2' => array(
'label' => 'Second page',
'route' => 'route-2'
),
),
),
您已经有到达第一页(route-1
)和第二页(route-2
)的路由。
步骤二
一个工厂将把这个转换成导航对象结构,您需要先创建一个该类。在您的MyModule/Navigation/Service目录中创建一个名为SecondaryNavigationFactory.php
的文件。
namespace MyModule\Navigation\Service;
use Zend\Navigation\Service\DefaultNavigationFactory;
class SecondaryNavigationFactory extends DefaultNavigationFactory
{
protected function getName()
{
return 'secondary';
}
}
注意这里我将名称secondary
设置为与您的导航键相同。
第三步
您必须将此工厂注册到服务管理器中。然后,该工厂就可以工作并将配置文件转换为Zend\Navigation
对象。您可以在module.config.php文件中执行此操作:
'service_manager' => array(
'factories' => array(
'secondary_navigation' => 'MyModule\Navigation\Service\SecondaryNavigationFactory'
),
)
看这里,我创建了一个名为secondary_navigation
的服务,在这个工厂函数中,会返回一个Zend\Navigation
实例。如果你现在调用$sm->get('secondary_navigation')
,你将会得到一个Zend\Navigation\Navigation
对象。
第四步
告诉视图辅助器使用这个导航而不是默认的。导航视图辅助程序接受一个"navigation"参数,您可以在其中指定要使用哪个导航。在这种情况下,服务管理器有一个名为secondary_navigation
的服务,这就是我们需要的那个。
<?= $this->navigation('secondary_navigation')->menu() ?>
现在你将会在这个视图助手中使用导航secondary
。
声明:这个答案与我在这个问题中回答的相同