web-dev-qa-db-fra.com

Comment rendre la vue ZF2 dans une réponse JSON?

Jusqu'à présent, j'ai compris comment renvoyer une réponse JSON typique dans Zend Framework 2. Premièrement, j'ai ajouté la variable ViewJsonStrategy à la section strategies de la configuration view_manager. Ensuite, au lieu de renvoyer une instance ViewModel à partir de l'action du contrôleur, je retourne une instance JsonModel avec toutes mes variables définies.

Maintenant que j'ai compris cette partie, je dois comprendre comment rendre une vue et la renvoyer dans cette réponse JSON. Dans ZF1, j'ai pu utiliser $this->view->render($scriptName), qui renvoyait le code HTML sous forme de chaîne. Dans ZF2, la méthode Zend\View\View::render(...) renvoie void.

Alors ... comment puis-je rendre un script de vue HTML et le renvoyer dans une réponse JSON en une seule requête?

C'est ce que j'ai en ce moment:

    if ($this->getRequest()->isXmlHttpRequest()) {
        $jsonModel = new JsonModel(...);

        /* @todo Render HTML script into `$html` variable, and add to `JsonModel` */
        return $jsonModel;
    } else {
        return new ViewModel(...);
    }
20
webjawns.com

OK, je pense avoir enfin compris ce que tu fais. J'ai trouvé une solution qui, je pense, correspond à vos critères. Bien que je suis sûr qu'il y a place à amélioration, il y a un travail manuel désagréable à faire ...

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

Comme vous pouvez le constater, le templateMap que je crée est ... méchant ... c’est embêtant et je suis sûr qu’il peut être considérablement amélioré. C'est une solution qui fonctionne mais pas une solution propre. Peut-être que quelqu'un serait en mesure de récupérer le PhpRenderer par défaut de ServiceLocator, probablement déjà instancié, avec son mappage de gabarit et de chemin d'accès, et il devrait alors être plus propre.

Grâce au commentaire de @DrBeza, le travail à accomplir pourrait être considérablement réduit. Maintenant, comme je le souhaitais initialement, nous allons saisir le générateur de vue avec tout le mappage de modèle intact et simplement restituer le ViewModel directement. Le seul facteur important est que vous devez spécifier le modèle entièrement qualifié à restituer (par exemple: "$ module/$ controller/$ action").

J'espère que cela vous aidera à commencer;)

PS: La réponse ressemble à ceci:

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

Vous pouvez utiliser un moyen plus simple de rendre la vue pour votre réponse 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);
}

Veuillez noter avant d'utiliser la classe JsonModel que vous devez configurer View Manager dans le fichier module.config.php de votre module. 

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

c'est un travail pour moi et j'espère que cela vous aidera.

7
Maksym Kalin

Avec ZF 3, vous pouvez obtenir le même résultat avec ce code

MyControllerFactory.php

public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
    $renderer = $container->get('ViewRenderer');

    return new MyController(
        $renderer
    );
}

MonContrôleur.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;
}
1
halanson