Переопределить стратегию просмотра для конкретного действия

У меня есть приложение, в котором мы используем стратегию AbstractRestfulController и Json. (У нас есть прямое требование для использования этого подхода). Итак, все наши запросы выполняются через jQuery Ajax с json. Теперь у меня есть особое требование для загрузки файла PDF, хранящегося на сервере. Я хочу использовать заголовки php/zend для загрузки файла вместо того, чтобы указывать фактический http-путь для файла.

Есть ли какое-либо решение для этого следующего подхода Restful. Я думаю о переопределении стратегии просмотра для конкретного действия, но не знаю, как это сделать?

У меня будет окончательный подход к использованию Default AbstractActionController для конкретного модуля, и я поместил в него свой код. Но если это будет единственное решение, которое у меня есть (поскольку перемещение кода текущего модуля в другой модуль выглядит плохой идеей)?


person kuldeep.kamboj    schedule 05.10.2012    source источник
comment
Похоже, раньше я меньше занимался исследованиями и разработками по этому вопросу. Поскольку простая установка обычного маршрутизатора без отдыха и соответствующее действие в контроллере сделали свое дело. Таким образом, мой Restful-контроллер выполняет оба типа действий REST через правило основного маршрутизатора, а действие без отдыха — через настраиваемые маршруты в module.config.php. Поэтому нет необходимости в каких-либо изменениях в Module.php.   -  person kuldeep.kamboj    schedule 12.02.2013


Ответы (1)


Ниже приведен пример добавления собственного стратегии просмотра, вы можете увидеть примеры в документации:

http://framework.zend.com/manual/2.0/en/modules/zend.view.quick-start.html

Легко изменить пример, чтобы проверить наличие данного контроллера/действия, если вы хотите пойти по этому пути.

<?php
namespace Application;

class Module
{
    public function onBootstrap($e)
    {
        // Register a "render" event, at high priority (so it executes prior
        // to the view attempting to render)
        $app = $e->getApplication();
        $app->getEventManager()->attach('render', array($this, 'registerJsonStrategy'), 100);
    }

    public function registerJsonStrategy($e)
    {
        $app          = $e->getTarget();
        $locator      = $app->getServiceManager();
        $view         = $locator->get('Zend\View\View');
        $phpStrateogy = $locator->get('PhpRendererStrategy');
        // or any you have setup in your config...
        $jsonStrategy = $locator->get('ViewJsonStrategy');

        $routeMatch = $e->getRouteMatch();
        /* @var $routeMatch \Zend\Mvc\Router\RouteMatch */
        $routeName = $routeMatch->getMatchedRouteName();
        if($routeName == 'myroute') {
            // possible change layout?
            //$controller->layout('app/layout/new_layout');
            // Attach strategy, which is a listener aggregate, at high priority
            //$view->getEventManager()->attach($jsonStrategy , 100);
            $view->getEventManager()->attach($phpStrateogy, 1);
        }
    }
}

В качестве альтернативы вы можете просто вернуть другой тип ViewModel, если обе стратегии включены, вы можете изменить используемую стратегию, вернув другую модель внутри вашего контроллера:

public function someAction()
{
    // will use JsonRenderer
    return new \Zend\View\Model\JsonModel(array('bob'));

    // Will use PHPRenderer
    return new \Zend\View\Model\ViewModel(array('bob'));
}
person Andrew    schedule 11.02.2013
comment
Я попробовал ваш код, но метод registerJsonStrategy так и не вызвался. Я думаю, поскольку ViewJsonStrategy включен в module.config.php, поэтому событие рендеринга никогда не вызывается. - person kuldeep.kamboj; 11.02.2013
comment
это был просто пример, он не предназначался для использования как есть, это просто пример того, как вы можете добавить новую стратегию. вы, вероятно, могли бы использовать и другие события, такие как отправка. - person Andrew; 11.02.2013
comment
если уже есть jsonViewStrategy с более высоким приоритетом, то он будет вызываться первым, попробуйте использовать меньший номер приоритета и т. д. - person Andrew; 11.02.2013
comment
Я уже использую ViewJsonStrategy в части стратегии module.config.php, так как все контроллеры используют шаблон REST по умолчанию. Мне нужно разрешить PhpRendererStrategy для определенного метода, который я намерен использовать для загрузки файла. - person kuldeep.kamboj; 11.02.2013
comment
затем замените jsonStrategy конкретной стратегией (PHP), имеющейся у вас в конфигурации службы, и измените код, чтобы отразить это. Также попробуйте установить более низкий приоритет в методе присоединения, чтобы убедиться, что он опережает другие стратегии. - person Andrew; 11.02.2013
comment
Хорошо, код работает нормально, только некоторые конфликты имен маршрутов создают проблемы. Я думаю о другом подходе, если для PhpRenderer следует разрешить несколько правил маршрутизации без использования условного IF или SWITCH в module.php. Но все же, это лучше и единственный доступный ответ до сих пор. - person kuldeep.kamboj; 11.02.2013
comment
Вы можете получить контроллер и имя действия из объекта RouteMatch, который вы можете добавить в свой условный оператор ;-) - person Andrew; 11.02.2013
comment
Я думаю, что если у вас включены обе стратегии в конфигурации, будет выбрана правильная, если вы вернете JsonModel или ViewModel внутри вашего контроллера/действия. - person Andrew; 11.02.2013