20

これまで、Zend Framework 2で一般的なJSON応答を返す方法を理解しました。最初に、構成ViewJsonStrategystrategiesセクションにを追加しました。view_manager次に、ViewModelコントローラーアクションからインスタンスを返す代わりにJsonModel、すべての変数が設定されたインスタンスを返します。

その部分を理解したので、ビューをレンダリングしてそのJSON応答内に返す方法を理解する必要があります。ZF1では$this->view->render($scriptName)、HTMLを文字列として返すを使用できました。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(...);
    }
4

4 に答える 4

48

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は...厄介です...面倒で、かなり改善できると確信しています。これは実用的なソリューションですが、クリーンなソリューションではありません。おそらく、テンプレートとパスのマッピングを使用して、おそらくすでにインスタンス化されているデフォルトのPhpRendererをServiceLocatorから取得できる可能性があります。そうすれば、よりクリーンになるはずです。

@DrBezaのコメントのおかげで、実行する必要のある作業をかなり減らすことができました。ここで、最初に望んでいたように、すべてのテンプレートマッピングをそのままにしてビューレンダラーを取得し、ViewModelを直接レンダリングします。唯一の重要な要素は、レンダリングする完全修飾テンプレートを指定する必要があることです(例: "$ module / $ controller / $ action")

私はこれがあなたが始めることを願っています;)

PS:応答は次のようになります:

Object:
    html: "<h1>Hello World</h1>"
    jsonArray: Array[6]
    jsonVar1: "jsonVal2"
于 2012-09-29T08:39:26.317 に答える
8

より簡単な方法を使用して、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ファイルでViewManagerを構成する必要があることに注意してください。

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

それは私のための仕事であり、それがあなたを助けることを願っています。

于 2013-08-10T15:14:55.413 に答える
2

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;
}
于 2017-02-26T21:48:06.263 に答える
-2

いつものように、フレームワーク開発者は、複雑かもしれないのになぜ単純なのかという規則に従って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;

少なくともzf2.0.0では、応答としてAJAXがnullになりました

于 2012-09-26T03:56:01.650 に答える