Как избежать обертывания ответа содержимым при возврате ViewModel в действии контроллера?

Используя Zend Framework 2 и AbstractRestfulController, где действие getList реализовано следующим образом:

public function getList() {
    return new ViewModel(array(
        'entities' = array(1 => array(/*..*/), 2 => array(/*..*/))
    ));
}

Я добавил JsonStrategy в диспетчер представлений, поэтому, когда мой UA отправляет Accept: text/html, ZF2 использует правильное представление для форматирования данных. Когда мой UA отправляет Accept: application/json, ZF2 (правильно) отвечает application/json и JSON кодирует данные.

Но теперь все объекты заключены в узел «контент» (свойство ViewModel::$captureTo).

Если контроллер действий возвращает JsonModel, я могу этого избежать. Но тогда JsonStrategy всегда отвечает application/json без проверки Accept.

Есть ли способ избежать этого при использовании ViewModel, а не JsonModel?


person André Roaldseth    schedule 06.11.2012    source источник


Ответы (2)


Для получения решения я делаю что-то вроде этого:

1 - Создайте новый MasterControllerClass, мои новые контроллеры «расширяют MasterControllerClass»

abstract class MasterControllerClass extends AbstractActionController 
private $_jsonFlag = false;

public function onDispatch(MvcEvent $e)
{
    $this->preDispatch($e);
    $action = parent::onDispatch($this->getEvent());
    $this->postDispatch($e);
    return $action;
}

public function postDispatch(MvcEvent $e)
{
    $this->_jsonFlag ?: $this->viewConfig($e);
}

public function json($value, $sucess = true)
{
    $this->_jsonFlag = true;
    return new \Zend\View\Model\JsonModel(array(
        'data' => $value,
        'success' => $sucess,
    ));
}

2 - В моем контроллере я вызову $this->json('значения для передачи в javascript', true или false, true == успех, false == сбой)

Это решило мою проблему, теперь я могу передать json своим javascripts.

person Jose Rafael Mendes Barbosa    schedule 08.11.2012
comment
Я хочу, чтобы мои контроллеры совершенно не обращали внимания на то, как отправляется ответ, чтобы решить, должен ли это быть JSON или HTML, уровень представления. - person André Roaldseth; 08.11.2012

Эта проблема устранена в Zend Framework 2.0.4, но не идеальным образом. Они добавили новый плагин контроллера под названием acceptableViewModelSelector, который можно использовать следующим образом:

class SomeController extends AbstractActionController
{
    protected $acceptCriteria = array(
        'Zend\View\Model\JsonModel' => array(
            'application/json',
        ),
        'Zend\View\Model\FeedModel' => array(
            'application/rss+xml',
        ),
    );

    public function apiAction()
    {
        $viewModel = $this->acceptableViewModelSelector($this->acceptCriteria);

        // Potentially vary execution based on model returned
        if ($viewModel instanceof JsonModel) {
            // ...
        }
    }
}

Когда он решит создать JsonModel, ответ будет правильно отображаться без оболочки «контента». Надеялся на более элегантное решение, чтобы можно было избежать логики представления в контроллерах, но исправление не было создано для непосредственного решения проблемы.

person André Roaldseth    schedule 28.11.2012