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



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

现在我已经弄清楚了这一部分,我需要了解如何呈现视图并在JSON响应中返回它。在ZF1中,我能够使用$this->view->render($scriptName),它将HTML作为字符串返回。在ZF2中,ZendViewView::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(...);
}

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

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响应的视图。

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 = ZendJsonJson::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;
}

像往常一样,框架开发人员对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 ZendViewModelJsonModel;
....

$result = new JsonModel($arr);
return $result;

AJAX至少在zf 2.0.0 中作为响应为null

最新更新