2

我需要将 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) 

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

从手册中,关于 The Forward Plugin

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

从手册中,关于可用控制器

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

AbstractActionController 实现了以下每个接口:

Zend\Stdlib\DispatchableInterface Zend\Mvc\InjectApplicationEventInterface Zend\ServiceManager\ServiceLocatorAwareInterface Zend\EventManager\EventManagerAwareInterface

所以我的FooControllerextends AbstractActionController,它实现ServiceLocatorAwareInterface了,所以 Forward 必须工作,但它没有。我错过了什么?如何让它发挥作用?

4

4 回答 4

3

您应该记住,调度插件通过名称从服务管理器获取要调度的控制器。因此,您应该使用正确的名称而不仅仅是类名。

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

可能是你叫 IS FooController,然后忘了我刚才说的

于 2012-11-20T14:55:42.293 回答
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
                    ),
                ),
            ),
        ),
    ),
于 2013-12-18T08:27:09.007 回答
1

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

return array(
    'controllers' => array(
        'invokables' => array(
             'FooController' => 'Namespace/Controller/FooController'
              ...
         ),
    )
 )
于 2013-02-05T14:00:00.693 回答
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'

于 2013-04-18T11:11:48.653 回答