ZF2: Плагин Forward контроллера не работает. Как заставить это работать?
Мне нужно перенаправить запрос ajax другому методу Action текущего контроллера. Я использую плагин Forward, но он не работает. В руководстве есть пример того, как использовать плагин 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)
Если я не использую Forward, все работает нормально, запрос приходит к indexAction
просто хорошо. Только Форвард выбрасывает ошибку.
Из руководства о плагине Forward:
Чтобы плагин Forward работал, вызывающий его контроллер должен быть ServiceLocatorAware; в противном случае плагин не сможет получить настроенный и внедренный экземпляр запрошенного контроллера.
Из руководства о доступных контроллерах:
Реализация каждого из вышеперечисленных интерфейсов является уроком избыточности; Вы не будете часто хотеть сделать это. Таким образом, мы разработали два абстрактных базовых контроллера, которые вы можете расширить, чтобы начать работу.
AbstractActionController реализует каждый из следующих интерфейсов:
Zend \ Stdlib \ DispatchableInterface Zend \ Mvc \ InjectApplicationEventInterface Zend \ ServiceManager \ ServiceLocatorAwareInterface Zend \ EventManager \ EventManagerAwareInterface
Так что мой FooController
продолжается AbstractActionController
, который реализует ServiceLocatorAwareInterface
Так что Форвард должен работать, но это не так. Что я упустил? Как заставить это работать?
4 ответа
Вы должны помнить, что диспетчерский плагин получает диспетчер для отправки от менеджера сервиса по имени. Поэтому вы должны использовать правильное имя, а не только имя класса.
Посмотрите в своей конфигурации массив controllers.invokables. В нем должно быть указано, какое имя сервиса соответствует какому FQCN.
Возможно, вас зовут IS FooController, а потом забудьте, что я только что сказал
Попробуй это:
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
),
),
),
),
),
Вы должны использовать полностью определенное имя при вызове контроллера, так что 'FooController' также должен находиться в пространстве имен. Также вы должны добавить контроллер в список активируемых файлов в файлах конфигурации модуля, например:
return array(
'controllers' => array(
'invokables' => array(
'FooController' => 'Namespace/Controller/FooController'
...
),
)
)
Попробуй это:
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'