2

我需要将ajax请求转发给当前控制器的其他Action方法。我使用Forward插件,但它不起作用。还有就是手册中有关如何使用转发插件的例子:ZF2:控制器的Forward插件不起作用。如何使它工作?

$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就好了。只有向前引发错误。

From the manual, about The Forward Plugin

对于正向插件工作时,控制器调用它必须是 ServiceLocatorAware;否则,该插件将无法检索到所请求的控制器的配置和注入实例 。

From the manual, about Available Controllers

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

AbstractActionController实现以下每个接口:

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

所以我FooController延伸AbstractActionController ,它实现了ServiceLocatorAwareInterface,所以Forward必须工作,但它不会。我错过了什么?如何使它工作?

回答

3

您应该记住,dispatch插件可以让控制器通过名称从服务管理器分派。因此,您应该使用正确的名称而不仅仅是类名。

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

这可能是你的名字是FooController的,然后忘了我刚才说的

1

呼叫控制器时,应使用完全合格的名称,所以“FooController的”也应该被命名空间。 此外,您应该添加控制器在模块配置文件的invokables的列表,例如:

return array(
    'controllers' => array(
     'invokables' => array(
      'FooController' => 'Namespace/Controller/FooController' 
       ... 
     ), 
    ) 
) 
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'

1

试这样的:

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

你module.config.php网络le是这样的:

'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 
        ), 
       ), 
      ), 
     ), 
    ),