1

I've been working through the ZF2 tutorial and I'm trying to rework the indexAction method in the Controller so I do not need to create a new ViewModel object every time.

I added an onBootstrap method to the Module with the following code:

    $di = new \Zend\Di\Di;
    $di->instanceManager()->setParameters('Album\ViewModel', array('albums' => $config-     >albums));

And I changed the indexAction method to:

    return $di->get('Album\ViewModel');

Can anyone tell me where I'm going wrong or what I should be doing instead?

4

2 に答える 2

1

You can just return an array from Actions inside Controllers and ZF2'll create a ViewModel around it itself. Not quite sure that's what you're after, but it might be.

于 2012-09-26T17:14:24.760 に答える
1

Steve Griffiths' answer should work if you're just trying to save code. If you want to extend this to more general dependency injection for your action controllers then I would implement your controllers as factories rather than invokables. However, if you're just trying to populate the ViewModel with data then this flexibility will likely be overkill. For example, in your module.config.php file you could add something like the following:

'controllers' => array(
    'factories' => array(
        'FooModule\Controller\FooController' => 'FooModule\Service\FooControllerFactory',
    ),
),

Then, when you call the controller in your application code via ZF2's MVC routing, it will be called using whatever instantiation code you put in that factory class. The code for that could look something like the following, depending on the dependencies you want to instantiate it with.

<?php

namespace FooModule\Service;

use FooModule\Controller\FooController; // actual controller code
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\View\Model\ViewModel;

class FooControllerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $controllers)
    {
        $services    = $controllers->getServiceLocator();
        $fooBar = $services->get('foo_bar_service'); // a service you registered already in the service manager
        $view = new ViewModel();
        $controller  = new FooController();
        $controller->setAuthService($authService);
        return $controller;
    }
}

As a result, you could access the $fooBar service from within your controller without any extra DI as follows:

<?php

namespace FooModule\Controller;

use Zend\Authentication\FooBarService;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

class FooController extends AbstractActionController
{   
    protected $fooBar; // already injected by your factory
    protected $view; // ViewModel object also injected by your factory

    public function indexAction()
    {
        $result = $this->fooBar->doSomething();
        $this->view->setVariable('name', $result);
        return $this->view;
    }
}

Again, might be overkill but I wanted to recommend it in case more flexible dependency injection is relevant to your use case.

于 2012-09-28T00:41:06.283 に答える