Как визуализировать представление ZF2 в ответе JSON?
До сих пор я выяснил, как вернуть типичный ответ JSON в Zend Framework 2. Сначала я добавил раздел ViewJsonStrategy
в strategies
конфигурации view_manager
. Затем вместо того, чтобы возвращать экземпляр ViewModel
из действия контроллера, я возвращаю экземпляр JsonModel
со всеми моими переменными.
Теперь, когда я вычислил эту часть, мне нужно понять, как визуализировать представление и вернуть его в этом ответе JSON. В ZF1 я смог использовать $this->view->render($scriptName)
, который вернул HTML в виде строки. В ZF2 метод Zend\View\View::render(...)
возвращает void
.
Итак... как я могу отобразить HTML-представление script и вернуть его в ответ 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(...);
}
Ответы
Ответ 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;
}
Как вы можете видеть, шаблонMap я создаю... неприятный... это раздражает, и я уверен, что он может быть улучшен совсем немного. Это рабочее решение, но просто не чистое. Возможно, каким-то образом можно было бы захватить, возможно, уже созданный по умолчанию PhpRenderer по умолчанию из ServiceLocator с его шаблоном и отображением пути, а затем он должен быть более чистым.
Благодаря комментарию от @DrBeza работа, которую необходимо выполнить, может быть уменьшена на справедливую сумму. Теперь, как я и хотел, мы будем захватывать viewrenderer с полным сохранением шаблона и просто визуализировать ViewModel напрямую. Единственным важным фактором является то, что вам нужно указать полностью соответствующий шаблон для рендеринга (например: "$ module/$controller/$action" )
Надеюсь, это поможет вам начать: wink
PS: Ответ выглядит следующим образом:
Object:
html: "<h1>Hello World</h1>"
jsonArray: Array[6]
jsonVar1: "jsonVal2"
Ответ 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 вам необходимо настроить View Manager в файле module.config.php вашего модуля.
'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, следуя правилу, почему простой, если может быть сложным. Это простое решение
в контроллере script
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 получил нулевой ответ как минимум в zf 2.0.0