В моем контроллере я создаю объект Navigation и передаю его в представление
$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 не может выполняться, так как экземпляр Zend \ Mvc \ Router \ RouteStackInterface состоит из Zend \ View \ Helper \ Navigation \ AbstractHelper.php в строке 471
Но навигация, которую я использую в макете, так как она написана здесь: http://adam.lundrigan.ca/2012/07/quick-and-dirty-zf2-zend-navigation/ работает. Какая у меня ошибка?
Спасибо.
Проблема заключается в отсутствии Router (или, точнее, Zend\Mvc\Router\RouteStackInterface
). Стек маршрута представляет собой набор маршрутов и может использовать имя маршрута для его преобразования в URL-адрес. В основном он принимает имя маршрута и создает для вас URL-адрес:
$url = $routeStack->assemble('my/route');
Это происходит и внутри страниц MVC Zend\Navigation
. На странице есть параметр route
и когда есть доступный маршрутизатор, страница собирает собственный URL (или в Zend\Navigation
terms, 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
навигацию по 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 / Navigation / Service.
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
Кстати. вам не нужно определять controller
и action
если вы определяете route
, только если ваш маршрут является общим и контроллер / действие являются переменными сегментами.
Проблема в том, что маршруты не могут быть разрешены без маршрутизатора. Я бы ожидал, что класс навигации решит эту проблему, но, очевидно, вам нужно сделать это самостоятельно. Я просто написал помощник вида, чтобы представить маршрутизатор с страницами 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; } }
Не забудьте добавить помощник вида в свой конфиг как invokable instance:
'view_helpers' => array( 'invokables' => array( 'registerNavigationRouter' => 'JarJar\View\Helper\RegisterNavigationRouter' ) ),
Это не отличное решение, но оно работает.