2012-09-16 10 views
20

Finora, ho capito come restituire una tipica risposta JSON in Zend Framework 2. Innanzitutto, ho aggiunto lo ViewJsonStrategy alla sezione strategies della configurazione view_manager. Quindi, invece di restituire un'istanza ViewModel dall'azione del controller, restituisco un'istanza JsonModel con tutte le mie variabili impostate.Come rendere la vista ZF2 all'interno della risposta JSON?

Ora che ho capito questo pezzo, ho bisogno di capire come rendere una vista e restituirla all'interno di quella risposta JSON. In ZF1, ero in grado di usare $this->view->render($scriptName), che restituiva l'HTML come una stringa. In ZF2, il metodo Zend\View\View::render(...) restituisce void.

Quindi ... come posso eseguire il rendering di uno script di visualizzazione HTML e restituirlo in una risposta JSON in una richiesta?

Questo è ciò che ho in questo momento:

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

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

Hey Sto solo tornando ad esso in quanto i' anche a questo. Qual è esattamente il tuo problema? Quando si restituisce un jsonModel (array ($ data)), la risposta è json. Non si vuole rendere alcuna vista o qualsivoglia cosa quando si restituisce json Oo – Sam

+0

Ho bisogno di eseguire il rendering di una vista parziale all'interno della risposta JSON. Esempio: '{" html ":" Sono una risposta HTML "}'. –

risposta

47

OK, credo di aver finalmente capito quello che stai facendo. Ho trovato una soluzione che penso corrisponda ai tuoi criteri. Anche se io sono sicuro che ci sia spazio per migliorare, come c'è qualche brutto lavoro manuale da fare ...

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

Come si può vedere, il templateMap genero è ... brutto ... è fastidioso e sono sicuro che può essere migliorato da un bel po '. È una soluzione funzionante, ma non pulita. Forse in qualche modo uno sarebbe in grado di afferrare il PhpRenderer predefinito, probabilmente già istanziato, dal ServiceLocator con la sua mappatura template e path e quindi dovrebbe essere più pulito.

Grazie al commento di @DrBeza, il lavoro necessario da eseguire potrebbe essere ridotto di una certa quantità. Ora, come inizialmente volevo, prenderemo il viewrenderer con tutti i template template intatti e semplicemente renderizziamo ViewModel direttamente. L'unico fattore importante è che è necessario specificare il modello completo per il rendering (ad esempio: "$ modulo/$ regolatore/$ azione")

Spero che questo vi permetterà di cominciare però;)

PS: risposta assomiglia a questo:

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

Apprezzo la risposta, ma mi sento come un disco rotto. Questo è utile, ma non risponde alla mia domanda. Devo restituire l'HTML in una risposta JSON, che includerà altre variabili, potenzialmente più viste. –

+0

@ webjawns.com Ho risolto la mia risposta, spero che questo ti possa iniziare. – Sam

+0

isXmlHttpRequest() può essere ignorato btw, era solo per me per rendere il mio modello da cui chiamo la richiesta ajax;) – Sam

-2

Come quadro di consueto cosa sviluppatore pasticciare AJAX seguendo la regola per cui semplice se potrebbe essere complessa Ecco soluzione semplice nello script di controllo

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

Questo funziona in ZF1 e ZF2 così Non c'è bisogno di vista scrpt affatto

Se si utilizza consiglio di ZF2 creatore

use Zend\View\Model\JsonModel; 
.... 


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

AJAX ottenuto nulla in risposta, almeno in ZF 2.0.0

+0

I * serve * per visualizzare uno script di visualizzazione all'interno della risposta Ajax. –

+0

In questo modo: '{" html ":" Sono una risposta HTML "}'. –

6

È possibile utilizzare il modo più semplice per eseguire il rendering vista per la risposta 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); 
} 

Si prega di notare prima classe di uso JsonModel è necessario config View Manager in module.config.php file del modulo.

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

è lavoro per me e spero che ti aiuti.

1

In ZF 3 è possibile ottenere lo stesso risultato con questo codice

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