Php Zend框架2:导航
在控制器中,我创建导航对象并将其传递给视图Php Zend框架2:导航,php,zend-framework2,Php,Zend Framework2,在控制器中,我创建导航对象并将其传递给视图 $navigation = new \Zend\Navigation\Navigation(array( array( 'label' => 'Album', 'controller' => 'album', 'action' => 'index', 'route' => 'album', ), ));
$navigation = new \Zend\Navigation\Navigation(array(
array(
'label' => 'Album',
'controller' => 'album',
'action' => 'index',
'route' => 'album',
),
));
有人试图使用它
<?php echo $this->navigation($this->navigation)->menu() ?>
并获取错误:
致命错误:Zend\Navigation\Exception\DomainException:Zend\Navigation\Page\Mvc::getHref无法执行,因为第471行的Zend\View\Helper\Navigation\AbstractHelper.php中没有Zend\Mvc\Router\RouteStackInterface实例
但我在布局中使用的导航,正如这里写的:有效。我犯了什么错
谢谢。顺便说一句。如果定义了
路由
,则无需定义控制器
和操作
,前提是您的路由是通用的,并且控制器/操作是可变段。问题在于缺少路由器(或者更准确地说,是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);
}
}
}
正如您所看到的,它是一个递归函数,将路由器注入到每个页面中。乏味的因此,有一家工厂为您做这件事。要做到这一点,有四个简单的步骤
第一步
首先将导航配置放在模块配置中。正如您有一个默认导航一样,您可以创建第二个辅助导航
'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\u导航
,工厂将返回一个Zend\navigation
实例。如果现在执行$sm->get('secondary_navigation')
,您将看到这是一个Zend\navigation\navigation
对象
第四步
告诉视图帮助器使用此导航,而不是默认导航。导航视图帮助器接受一个“导航”参数,您可以在其中声明所需的导航。在这种情况下,服务管理器有一个服务辅助导航
,这正是我们需要的
<?= $this->navigation('secondary_navigation')->menu() ?>
现在,您将在此视图帮助器中使用导航辅助
披露:这个答案与我在这个问题上给出的答案相同:问题确实是没有路由器就无法解决路由问题。我希望navigation类能够解决这个问题,但很明显,您必须自己解决这个问题。我刚刚写了一个视图助手来介绍带有MVC页面的路由器
以下是我在视图中使用它的方式:
$navigation = $this->navigation();
$navigation->addPage(
array(
'route' => 'language',
'label' => 'language.list.nav'
)
);
$this->registerNavigationRouter($navigation);
echo $navigation->menu()->render();
视图辅助对象:
<?php
namespace JarJar\View\Helper;
use Zend\View\Helper\AbstractHelper;
use Zend\View\Helper\Navigation;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Navigation\Page\Mvc;
class RegisterNavigationRouter extends AbstractHelper implements ServiceLocatorAwareInterface
{
protected $serviceLocator;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
public function __invoke(Navigation $navigation)
{
$router = $this->getRouter();
foreach ($navigation->getPages() as $page) {
if ($page instanceof Mvc) {
$page->setRouter($router);
}
}
}
protected function getRouter()
{
$router = $this->getServiceLocator()->getServiceLocator()->get('router');
return $router;
}
}
这不是一个很好的解决方案,但很有效。你说得对,谢谢你的评论。但如果是这样的话,公告页面错误仍然存在。代码运行时的唯一选项,看起来是这样的:$navigation=new\Zend\navigation\navigation(数组(数组('label'=>'Album','uri'=>'/),)
当url直接设置时。hm dunno,但是module.php中有这个吗<代码>$application=$e->getApplication()$eventManager=$application->getEventManager()$moduleRouteListener=新的moduleRouteListener()$模块OutElistener->attach($eventManager)
Yes在Module.php中,在onBootstrap方法中,我有完全相同的代码。有趣的是,我的视图中的url视图帮助程序工作正常。代码$this->url('album/default',array('controller'=>'album','action'=>'edit','id'=>$id))
运行良好,并在页面上显示链接。不清楚是否会干扰菜单的正确显示。如果有什么想法,我会很高兴听到的。谢谢。这是一个很好的例子。在我想使用局部视图进行渲染之前,它一直有效。我用这个作为我的主导航,但这不重要。我使用的是:echo$this->navigation('navigation')->menu()->setPartial(数组('navigation.phtml','Application');致命错误:Zend\ServiceManager\Exception\ServiceNotFoundException:Zend\ServiceManager\ServiceManager::get无法为第471行的/myapp/vendor/zendframework/zendframework/library/Zend/View/Helper/Navigation/AbstractHelper.php中的菜单获取或创建实例
'view_helpers' => array(
'invokables' => array(
'registerNavigationRouter' => 'JarJar\View\Helper\RegisterNavigationRouter'
)
),