我需要将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
,因此转发必须正常工作,但事实并非如此。我错过了什么?如何使它工作?
答案 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
),
),
),
),
),