Implementing ServiceLocatorAwareInterface dependen

2019-09-02 08:41发布

问题:

EDITED (Code is updated and working for others)
For the overall idea of what's happening.

I'm trying to access post data from the view in the controller, without refreshing the page.

To do this I am executing the page controller by using a ViewHelper to call the Service below which then forwards back to the controller; afterwards I can manage the posted data in the page controller.

Everything works except the last step which is the forward(), I receive the error Call to undefined method AlbumModule\Service\postAlbumService::forward()

I understand I must implement the ServiceLocatorAwareInterface in order to use the forward() class, but what I've written doesn't seem to work.

            <?php
            namespace AlbumModule\Service;

            use Zend\ServiceManager\ServiceLocatorAwareInterface;
            use Zend\ServiceManager\ServiceLocatorInterface;

            class postAlbumService implements
                ServiceLocatorAwareInterface
            {
                protected $services;

                public function __construct() {
                    echo '<script>console.log("postAlbumService is Started")</script>';
                }

                public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
                {
                    $this->services = $serviceLocator;
                }

                public function getServiceLocator()
                {
                    return $this->services;
                }

                public function test(){
                    $cpm = $this->getServiceLocator()->get('controllerpluginmanager');
                    $fwd = $cpm->get('forward');
                    echo '<script>console.log("postAlbumService TEST() is Started")</script>';
                    return $fwd->dispatch('newAlbum', array('action' => 'submitAlbum'));
                }
            }

It seems as though I'm just having a dependency issue with the forward() class, but I'm not sure what the issue is.

EDIT-
Here is how I am calling the postAlbumService from the viewHelper

            <?php
            namespace AlbumModule\View\Helper;

            use Zend\View\Helper\AbstractHelper;

            class invokeIndexAction extends AbstractHelper
            {
             protected $sm;

                   public function test()
                    {
                        $this->sm->getServiceLocator()->get('AlbumModule\Service\postAlbumService')->test();
                    }

                    public function __construct($sm) {
                        $this->sm = $sm;
                    }
            }

Is there any way to call a specific class in the service being requested, after the dependencies are injected into the service?

回答1:

You're doing a couple of things wrong and you're misunderstanding some things...

First of all, forward() is a ControllerPlugin. You'll gain access to this method by accessing said manager via the ServiceLocator. An example could be this:

$cpm = $serviceLocator->get('controllerpluginmanager');
$fwd = $cpm->get('forward');
return $fwd->dispatch('foo/bar');

Now, to get the ServiceLocator into any of your Service-Classes you need Dependency Injection. One of the ways is to implement the ServiceLocatorAwareInterface. The ServiceManager of ZF2 has so called Listeners. These Listeners check for implemented interfaces and stuff like this. Whenever it finds a match, it injects the required dependencies via the interfaces given functions. The workflow looks like this:

ServiceManager get('FooBar');
    $ret = new FooBar();
    foreach (Listener) 
        if $ret instanceof Listener
             doInjectDependenciesInto($ret)
        end
    end
    return $ret

Now what does this tell you. This tells you, that within the __construct() of any of your classes NONE of your required dependencies are actually there. They only get injected AFTER the class/service has been instantiated.

On a last side-note, the given code example doesn't really make much sense ;) No matter what ServiceAction i'd like to access, you'd always return me to the "newAlbum" action...