【问题标题】:How to avoid wrapping response with "content" when returning ViewModel in controller action?在控制器操作中返回 ViewModel 时如何避免用“内容”包装响应?
【发布时间】:2012-10-26 17:41:07
【问题描述】:

使用 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 的同时,有什么办法可以避免它?

【问题讨论】:

    标签: php json viewmodel zend-framework2


    【解决方案1】:

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

    【讨论】:

      【解决方案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('values to pass to javascript', true or false, true == success, false == fail)

      它解决了我的问题,现在我可以将 json 传递给我的 javascripts。

      【讨论】:

      • 我希望我的控制器完全不知道响应是如何发送的,由视图层决定它应该是 JSON 还是 HTML。
      猜你喜欢
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 2021-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多