ZF2:Controller的Forward插件不起作用。如何使它工作?

时间:2012-11-18 15:21:08

标签: zend-framework2 zend-framework-mvc zend-framework-modules zend-framework-routing

我需要将ajax请求转发给当前控制器的另一个Action方法。我使用Forward插件但它不起作用。手册中有一个关于如何使用Forward Plugin的例子:

$foo = $this->forward()->dispatch('foo', array('action' => 'process')); 
return array(
    'somekey' => $somevalue,
    'foo'     => $foo, 
);

我的代码:

// From Ajax on the page. I apply to the indexAction of FooController,
// I use RegEx route
xhr.open('get', '/fooindex', true);


// My Controller
namespace Foo\Controller;

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

// I extend the AbstractActionController, the manual says it's important for the Forward Plugin to work
class FooController extends AbstractActionController {

    // This is the action I send my request from Ajax
    public function indexAction() {

        // if the request if Ajax request I forward the run to the nextAction method
        if ($this->getRequest()->isXmlHttpRequest()) {

            // I do as manual says
            $rs = $this->forward()->dispatch('FooController', array('action' => 'next'));
        }
    }


    public function nextAction() {

        // And I just want to stop here to see that the Forward Plugin works
        // But control doesn't reach here 
        exit('nextAction');
    }
}

我在控制台中遇到的错误是:

GET http://test.localhost/fooindex 500 (Internal Server Error) 

如果我不使用转发一切正常,请求来indexAction就好了。只有Forward会抛出错误。

From the manual, about The Forward Plugin

  

要使Forward插件正常工作,调用它的控制器必须是   ServiceLocatorAware;否则,插件将无法检索   已配置并注入所请求控制器的实例。

From the manual, about Available Controllers

  

实现上述每个接口都是冗余的教训;   你不会经常想要这样做。因此,我们开发了两个摘要,   您可以扩展基础控制器以开始使用。

     

AbstractActionController实现以下每个接口:

     

的Zend \ STDLIB \ DispatchableInterface   Zend的\的mvc \ InjectApplicationEventInterface   Zend的\的ServiceManager \ ServiceLocatorAwareInterface   的Zend \ eventmanager进行\ EventManagerAwareInterface

因此我的FooController扩展AbstractActionController,实现ServiceLocatorAwareInterface,因此转发必须正常工作,但事实并非如此。我错过了什么?如何使它工作?

4 个答案:

答案 0 :(得分:3)

你应该记住,dispatch插件让控制器按名称从服务管理器调度到。因此,您应该使用正确的名称,而不仅仅是类名。

在配置中查找controllers.invokables数组。这应该包含服务的哪个名称映射到FQCN。

你可能是你的名字IS FooController,然后忘记我刚刚说的话

答案 1 :(得分:1)

调用控制器时应该使用完全限定名,因此'FooController'也应该是命名空间。 此外,您应该在模块配置文件的invokable列表中添加控制器,例如:

return array(
    'controllers' => array(
        'invokables' => array(
             'FooController' => 'Namespace/Controller/FooController'
              ...
         ),
    )
 )

答案 2 :(得分:1)

试试这个:

class FooController extends AbstractActionController {
    public function indexAction() {
        return $this->forward()->dispatch('Bar\Controller\Bar',
            array(
                'action' => 'process',
                'somekey' => $somevalue,
            ));
    }
}

这里可以调用:'Bar\Controller\Bar' => 'Bar\Controller\Bar'

答案 3 :(得分:1)

试试这个:

class FooController extends AbstractActionController {
    public function indexAction() {
        return $this->forward()->dispatch('Foo',
            array(
                'action' => 'process',
                'somekey' => $somevalue,
            ));
    }
}

你的module.config.php文件是这样的:

'controllers' => array(
    'invokables' => array(
        'Foo' => 'Foo\Controller\FooController',   // <----- Module Controller
    ),
),

   'router' => array(
        'routes' => array(
            'foo' => array(
                'type'    => 'segment',
                'options' => array(
                    'route'    => '/foo[/:action][/:id]',  // <---- url format module/action/id
                    'constraints' => array(
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                        'id'     => '[0-9]+',
                    ),
                    'defaults' => array(
                        'controller' => 'Foo',  // <--- Defined as the module controller
                        'action'     => 'index',                   // <---- Default action
                    ),
                ),
            ),
        ),
    ),