Zend框架2:导航(Zend Framework 2: Navigation)

2019-08-01 05:52发布

在我的控制,我创建了导航对象,并把它传递给视图

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

有尝试使用它

<?php echo $this->navigation($this->navigation)->menu() ?>

并且得到错误:

致命错误:Zend的\导航\异常\ DomainException:Zend的\导航\页\的mvc :: getHref不能执行,因为没有Zend的\的mvc \路由器\ RouteStackInterface例如由在Zend的\查看\助手\导航\ AbstractHelper.php上线471

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

谢谢。

Answer 1:

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

$url = $routeStack->assemble('my/route');

出现这种情况的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);
    }
  }
}

正如你看到它是一个递归函数,注射进入路由器的每一页。 乏味! 因此,有一个工厂为你做到这一点。 有四个简单的步骤来实现这一目标。

第一步

把导航配置您的模块配置第一。 就像你有一个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

第二步

一家工厂将转换成一个导航对象结构这一点,你需要首先创建一个类。 创建文件SecondaryNavigationFactory.php在MyModule中/导航/服务目录。

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对象。

第四步

告诉视图助手来使用这个导航,而不是默认的。 导航视图助手接受“导航”参数在这里你可以说出你想要的导航。 在这种情况下,服务管理有服务secondary_navigation ,这是我们所需要的一个。

<?= $this->navigation('secondary_navigation')->menu() ?>

现在你将有导航secondary在这个视图助手使用。

披露:这个答案是一样的,因为我介绍了这个问题: https://stackoverflow.com/a/12973806/434223



Answer 2:

顺便说一句。 你不需要定义controlleraction ,如果你定义了一个route ,只有当你的路线是通用的,控制器/动作是可变的部分。



Answer 3:

这个问题确实是一个路由不能没有路由器来解决。 我希望导航类来解决这个问题,但很明显,你必须做你自己。 我只是写了一个视图助手与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;
    }
}

不要忘记添加视图助手在你的配置为可调用的实例:

'view_helpers' => array(
    'invokables' => array(
        'registerNavigationRouter' => 'JarJar\View\Helper\RegisterNavigationRouter'
    )
),

这不是一个很好的解决方案,但它的工作原理。



文章来源: Zend Framework 2: Navigation