【问题标题】:How to render ZF2 view within JSON response?如何在 JSON 响应中呈现 ZF2 视图?
【发布时间】:2017-02-27 05:48:06
【问题描述】:

到目前为止,我已经弄清楚了如何在 Zend Framework 2 中返回典型的 JSON 响应。首先,我将 ViewJsonStrategy 添加到 view_manager 配置的 strategies 部分。然后,我没有从控制器操作返回 ViewModel 实例,而是返回一个设置了所有变量的 JsonModel 实例。

现在我已经弄清楚了那部分,我需要了解如何呈现视图并在 JSON 响应中返回它。在 ZF1 中,我可以使用$this->view->render($scriptName),它将 HTML 作为字符串返回。在 ZF2 中,Zend\View\View::render(...) 方法返回void

那么...如何呈现 HTML 视图脚本并在一个请求中以 JSON 响应的形式返回它?

这就是我现在拥有的:

    if ($this->getRequest()->isXmlHttpRequest()) {
        $jsonModel = new JsonModel(...);

        /* @todo Render HTML script into `$html` variable, and add to `JsonModel` */
        return $jsonModel;
    } else {
        return new ViewModel(...);
    }

【问题讨论】:

  • 嘿,我只是回到它,因为我也参与其中。你的问题到底是什么?当您返回 jsonModel(array($data)) 时,响应为 json。您不想在返回 json Oo 时呈现任何视图或任何内容
  • 我需要在 JSON 响应中呈现部分视图。示例:{"html":"<tr><td>I'm an HTML response</td></tr>"}.

标签: php json zend-framework2 zend-framework-mvc


【解决方案1】:

好的,我想我终于明白你在做什么了。我找到了一个我认为符合您的标准的解决方案。虽然我确信还有改进的空间,因为有一些令人讨厌的手工工作要做......

public function indexAction()
{
  if (!$this->getRequest()->isXmlHttpRequest()) {
    return array();
  }

  $htmlViewPart = new ViewModel();
  $htmlViewPart->setTerminal(true)
               ->setTemplate('module/controller/action')
               ->setVariables(array(
                  'key' => 'value'
               ));

  $htmlOutput = $this->getServiceLocator()
                     ->get('viewrenderer')
                     ->render($htmlViewPart);

  $jsonModel = new JsonModel();
  $jsonModel->setVariables(array(
    'html' => $htmlOutput,
    'jsonVar1' => 'jsonVal2',
    'jsonArray' => array(1,2,3,4,5,6)
  ));

  return $jsonModel;
}

如您所见,我创建的 templateMap 是......讨厌......它很烦人,我相信它可以改进很多。这是一个可行的解决方案,但不是一个干净的解决方案。也许有人能够以某种方式从 ServiceLocator 中获取可能已经实例化的默认 PhpRenderer,并使用它的模板和路径映射,然后它应该更干净。

感谢@DrBeza 的评论,需要完成的工作可以减少相当多的数量。现在,正如我最初想要的那样,我们将获取所有模板映射完整的视图渲染器,并直接渲染 ViewModel。唯一重要的因素是您需要指定要呈现的完全限定模板(例如:“$module/$controller/$action”)

我希望这能让你开始;)

PS:响应如下:

Object:
    html: "<h1>Hello World</h1>"
    jsonArray: Array[6]
    jsonVar1: "jsonVal2"

【讨论】:

  • 我很欣赏您的回复,但我觉得自己像是破纪录。这很有帮助,但它不能回答我的问题。我需要在 JSON 响应中返回 HTML,其中将包括其他变量——可能是多个视图。
  • @webjawns.com 我已经编辑了我的答案,希望这能让你开始。
  • @Sam 您可以使用以下命令来简化所有操作:$htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render('test/test', $viewModel)。
  • @DrBeza 感谢您的澄清,我认为这是可能的,但简单不知道如何:)我会尝试修改答案:)
  • 如果您使用的是 Twig,请将 get('viewrenderer') 替换为 get('ZfcTwigRenderer')
【解决方案2】:

您可以使用更简单的方式为您的 JSON 响应呈现视图。

public function indexAction() {
    $partial = $this->getServiceLocator()->get('viewhelpermanager')->get('partial');
    $data = array(
            'html' => $partial('MyModule/MyPartView.phtml', array("key" => "value")),
            'jsonVar1' => 'jsonVal2',
            'jsonArray' => array(1, 2, 3, 4, 5, 6));
    $isAjax = $this->getRequest()->isXmlHttpRequest());
    return isAjax?new JsonModel($data):new ViewModel($data);
}

请注意,在使用 JsonModel 类之前,您需要在模块的 module.config.php 文件中配置 View Manager。

'view_manager' => array(
        .................
        'strategies' => array(
            'ViewJsonStrategy',
        ),
        .................
    ),

这对我有用,希望对你有所帮助。

【讨论】:

    【解决方案3】:

    在 ZF 3 中,您可以使用此代码获得相同的结果

    MyControllerFactory.php

    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $renderer = $container->get('ViewRenderer');
    
        return new MyController(
            $renderer
        );
    }
    

    MyController.php

    private $renderer;
    
    public function __construct($renderer) {
        $this->renderer = $renderer;
    }
    
    public function indexAction() {
    
        $htmlViewPart = new ViewModel();
        $htmlViewPart
                ->setTerminal(true)
                ->setTemplate('module/controller/action')
                ->setVariables(array('key' => 'value'));
    
        $htmlOutput = $this->renderer->render($htmlViewPart);
    
        $json = \Zend\Json\Json::encode(
            array(
                'html' => $htmlOutput,
                'jsonVar1' => 'jsonVal2',
                'jsonArray' => array(1, 2, 3, 4, 5, 6)
            )
        );
    
        $response = $this->getResponse();
        $response->setContent($json);
    
        $response->getHeaders()->addHeaders(array(
            'Content-Type' => 'application/json',
        ));
        return $this->response;
    }
    

    【讨论】:

      【解决方案4】:

      像往常一样,框架开发人员会按照规则为什么简单,如果可能很复杂,会弄乱 AJAX 的事情这是简单的解决方案 在控制器脚本中

      public function checkloginAction()
      {
         // some hosts need to this some not 
         //header ("Content-type: application/json");  // this work
         // prepare json aray ....
         $arr = $array("some" => .....);
         echo json_encode($arr); // this works
         exit;
      }
      

      这也适用于 ZF1 和 ZF2 根本不需要查看脚本

      如果您使用 ZF2 创建者的建议

      use Zend\View\Model\JsonModel;
      ....
      
      
       $result = new JsonModel($arr);
       return $result;
      

      至少在 zf 2.0.0 中,AJAX 的响应为 null

      【讨论】:

      • 需要在 Ajax 响应中呈现视图脚本。
      • 像这样:{"html":"&lt;strong&gt;I'm an HTML response&lt;/strong&gt;"}.
      猜你喜欢
      • 1970-01-01
      • 2012-10-09
      • 1970-01-01
      • 2019-11-02
      • 2019-12-15
      • 2011-01-28
      • 2011-07-06
      • 2011-01-06
      • 1970-01-01
      相关资源
      最近更新 更多