问题
I'm trying to implement my zend navigation from a container in ZF3. I have successfully created navigation with this quick start tutorial introducing navigation directly in config/autoload/global.php
or config/module.config.php
files:
https://docs.zendframework.com/zend-navigation/quick-start/
But now I need to make it work these with the helpers to allow navigation modifications from the controller, using the "Navigation setup used in examples" section:
https://docs.zendframework.com/zend-navigation/helpers/intro/
This is my Module.php
namespace Application;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\View\HelperPluginManager;
class Module implements ConfigProviderInterface
{
public function getViewHelperConfig()
{
return [
'factories' => [
// This will overwrite the native navigation helper
'navigation' => function(HelperPluginManager $pm) {
// Get an instance of the proxy helper
$navigation = $pm->get('Zend\View\Helper\Navigation');
// Return the new navigation helper instance
return $navigation;
}
]
];
}
public function getControllerConfig()
{
return [
'factories' => [
$this->getViewHelperConfig()
);
},
],
];
}
}
And this is my IndexController.php
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Navigation\Navigation;
use Zend\Navigation\Page\AbstractPage;
class IndexController extends AbstractActionController
{
private $navigationHelper;
public function __construct(
$navigationHelper
){
$this->navigationHelper = $navigationHelper;
}
public function indexAction()
{
$container = new Navigation();
$container->addPage(AbstractPage::factory([
'uri' => 'http://www.example.com/',
]));
$this->navigationHelper->plugin('navigation')->setContainer($container);
return new ViewModel([
]);
}
}
But then I get the following error:
Fatal error: Call to a member function plugin() on array in /var/www/html/zf3/module/Application/src/Controller/IndexController.php on line 50
In the tutorial they use the following statement:
// Store the container in the proxy helper:
$view->plugin('navigation')->setContainer($container);
// ...or simply:
$view->navigation($container);
But I don´t know what this $view
is, so I assume is my $navigation
from my Module.php. The problem is that, because is an array, it throws the error. The questions are:
- What am I doing wrong?
- Where this
$view
of the tutorial come from? - What I should pass from my Module.php to get it work?
Thanks in advance!
回答1:
Add into module.config.php
'service_manager' => [
'factories' => [
Service\NavManager::class => Service\Factory\NavManagerFactory::class,
],
],
'view_helpers' => [
'factories' => [
View\Helper\Menu::class => View\Helper\Factory\MenuFactory::class,
],
'aliases' => [
'mainMenu' => View\Helper\Menu::class,
],
],
Create Factory in Service Directory:
namespace Application\Service\Factory;
use Interop\Container\ContainerInterface;
use Application\Service\NavManager;
class NavManagerFactory {
/**
* This method creates the NavManager service and returns its instance.
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
$authService = $container->get(\Zend\Authentication\AuthenticationService::class);
$viewHelperManager = $container->get('ViewHelperManager');
$urlHelper = $viewHelperManager->get('url');
return new NavManager($authService, $urlHelper);
}
}
Create NavManager file :
namespace Application\Service;
class NavManager {
/**
* Auth service.
* @var Zend\Authentication\Authentication
*/
private $authService;
/**
* Url view helper.
* @var Zend\View\Helper\Url
*/
private $urlHelper;
/**
* Constructs the service.
*/
public function __construct($authService, $urlHelper) {
$this->authService = $authService;
$this->urlHelper = $urlHelper;
}
/**
* Menu render based on user role
*
* @return array
*/
public function getMenuItems() {
$navItem = array();
$url = $this->urlHelper;
$items = [];
$items[] = [
'label' => 'Dashboard',
'icon' => 'dashboard',
'link' => $url('home'),
'route' => ['home'],
];
$items[] = [
'label' => 'About Us',
'icon' => 'business',
'link' => $url('about', ['action'=>'index']),
'route' => ['about'],
];
$items[] = [
'label' => 'Service',
'icon' => 'service',
'link' => $url('service', ['action'=>'index']),
'route' => ['service'],
];
return $items;
}
Create Helper Factory
namespace Application\View\Helper\Factory;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use Application\View\Helper\Menu;
use Application\Service\NavManager;
/**
* This is the factory for Menu view helper. Its purpose is to
instantiate the helper and init menu items. */
class MenuFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
$navManager = $container->get(NavManager::class);
// Get menu items.
$items = $navManager->getMenuItems();
// Instantiate the helper.
return new Menu($items);
}
}
Create Helper :
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
/**
* This view helper class displays a menu bar.
*/
class Menu extends AbstractHelper {
/**
* Menu items array.
* @var array
*/
protected $items = [];
/**
* Active item's ID.
* @var string
*/
protected $activeItemId = '';
/**
* Constructor.
* @param array $items Menu items.
*/
public function __construct($items=[]) {
$this->items = $items;
}
/**
* Sets menu items.
* @param array $items Menu items.
*/
public function setItems($items) {
$this->items = $items;
}
/**
* Sets ID of the active items.
* @param string $activeItemId
*/
public function setActiveItemId($activeItemId) {
$this->activeItemId = $activeItemId;
}
/**
* Renders the menu.
* @return string HTML code of the menu.
*/
public function render() {
if (count($this->items)==0) {
return ''; // Do nothing if there are no items.
}
// Render items
foreach ($this->items as $item) {
$result .= $this->renderItem($item);
}
return $result;
}
protected function renderItem($item) {
// here you can integrate with HTML
return $item;
}
}
After add above codes,just add below code in your layout file :
echo $this->mainMenu()->render();
来源:https://stackoverflow.com/questions/39390067/zf3-zend-navigation-helper