これまでのところ、Zend Framework 2で典型的なJSON応答を返す方法を理解しました。最初に、ViewJsonStrategy
を_view_manager
_構成のstrategies
セクションに追加しました。次に、コントローラーアクションからViewModel
インスタンスを返す代わりに、すべての変数を設定したJsonModel
インスタンスを返します。
その部分を理解したので、ビューをレンダリングしてそのJSON応答内で返す方法を理解する必要があります。 ZF1では、HTMLを文字列として返す$this->view->render($scriptName)
を使用できました。 ZF2では、Zend\View\View::render(...)
メソッドはvoid
を返します。
では、どうすればHTMLビュースクリプトをレンダリングして、1つのリクエストで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は...厄介です...迷惑であり、かなり改善できると確信しています。これは実用的なソリューションですが、クリーンなソリューションではありません。おそらくどういうわけか、おそらくすでにインスタンス化されているデフォルトのPhpRendererを、テンプレートとパスマッピングを使用してServiceLocatorから取得できるため、よりクリーンなはずです。
@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を構成する必要があることに注意してください。
'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;
}