如何在JSON响应中呈现ZF2视图?

问题描述:

到目前为止,我已经想出了如何在Zend Framework 2中返回典型的JSON响应。首先,我将ViewJsonStrategy添加到view_manager配置的strategies部分。然后,我不返回控制器操作中的ViewModel实例,而是返回一个JsonModel实例,并设置了所有变量。如何在JSON响应中呈现ZF2视图?

现在我已经想出了这件作品,我需要了解如何渲染视图并在该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(...); 
    } 
+0

嘿,我只是回到它,因为我”达到同样的效果米也在。你的问题究竟是什么?当你返回一个jsonModel(array($ data))时,那么响应是json。你不想渲染任何视图或任何返回json Oo – Sam

+0

我需要渲染JSON响应中的部分视图。示例:'{“html”:“

​​我是HTML响应”}'。 –

OK,我想我终于明白你在做什么。我找到了一个我认为符合您的标准的解决方案。虽然我肯定有改进的余地,因为有做一些讨厌的手工...

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,然后它应该更清晰。

感谢评论ot @DBeBeza需要完成的工作可以减少相当数量。现在,正如我最初想要的那样,我们将抓住viewrenderer,并保留所有模板映射,并直接渲染ViewModel。唯一重要的因素是,你需要指定完全合格的模板来呈现(如:“$模块/ $控制器/ $行动”)

我希望这将让你开始虽然;)

PS:响应如下所示:

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

我很欣赏这种回应,但我觉得自己是一个破纪录。这很有帮助,但它不能回答我的问题。我需要在JSON响应中返回HTML,其中包含其他变量 - 可能包含多个视图。 –

+0

@ webjawns.com我已经编辑了我的答案,我希望这会让你开始。 – Sam

+0

isXmlHttpRequest()可以被忽略顺便说一句,只是为了呈现我的模板,我从中调用ajax请求;) – Sam

随着对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; 

AJAX了null作为响应,至少在ZF 2.0.0

+0

我*需要*在Ajax响应中呈现视图脚本。 –

+0

像这样:'{“html”:“我是一个HTML响应”}'。 –

您可以使用更简单的方法为您的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' => array(
     ................. 
     'strategies' => array(
      'ViewJsonStrategy', 
     ), 
     ................. 
    ), 

这是我的工作,并希望它可以帮助你。

在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; 
}