在控制器操作中返回ViewModel时,如何避免使用“content”包装响应?

时间:2012-11-06 17:57:19

标签: php json viewmodel zend-framework2

使用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时避免使用它?

2 个答案:

答案 0 :(得分:1)

为了获得解决方案,我会做这样的事情:

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。

答案 1 :(得分:0)

此问题已在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时,将在没有“content”包装器的情况下正确呈现响应。希望有一个更优雅的解决方案,这样可以避免控制器中的视图逻辑,但是没有创建修复来直接解决问题。