2012-09-16 12 views
20

Do tej pory dowiedziałem się, jak zwrócić typową odpowiedź JSON w Zend Framework 2. Najpierw dodałem ViewJsonStrategy do sekcji strategies konfiguracji view_manager. Następnie zamiast zwracania instancji ViewModel z akcji kontrolera zwracam instancję JsonModel ze wszystkimi ustawionymi zmiennymi.Jak renderować widok ZF2 w ramach odpowiedzi JSON?

Teraz, gdy wymyśliłem ten fragment, muszę zrozumieć, jak renderować widok i zwracać go w ramach tej reakcji JSON. W ZF1 mogłem użyć $this->view->render($scriptName), która zwróciła HTML jako ciąg znaków. W ZF2, metoda Zend\View\View::render(...) zwraca void.

Więc ... jak mogę renderować skrypt widoku HTML i zwracać go w odpowiedzi JSON w jednym żądaniu?

To co mam teraz:

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

Hej Ja tylko powracającego do niej odkąd” M na tym też. Czym dokładnie jest twój problem? Po zwróceniu jsonModel (array ($ data)), odpowiedzią jest json. Nie chcesz renderować żadnego widoku ani niczego, kiedy zwracasz json Oo – Sam

+0

Potrzebuję renderować częściowy widok wewnątrz odpowiedzi JSON. Przykład: '{" html ":" Jestem odpowiedzią HTML "}'. –

Odpowiedz

47

OK, myślę, że w końcu zrozumiał, co robisz. Znalazłem rozwiązanie, które według mnie pasuje do twoich kryteriów. Choć jestem pewien, że istnieje pole do poprawy, a nie jakiś paskudny czna do zrobienia ...

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

Jak widać, templateMap tworzę jest ... ... to przykre i denerwujące jestem pewien, że można go poprawić nieco. To działające rozwiązanie, ale nie czyste. Być może jakoś uda się uchwycić, prawdopodobnie już utworzony, domyślny PhpRenderer z ServiceLocator z jego mapowaniem i mapowaniem ścieżek, a następnie powinno być czystsze.

Dzięki komentarzowi @DrBeza praca, którą trzeba wykonać, może zostać zmniejszona o uczciwą kwotę. Teraz, tak jak początkowo chciałem, złapiemy viewrender z nietkniętym całym odwzorowaniem szablonów i bezpośrednio wyrenderujemy ViewModel. Jedynym ważnym czynnikiem jest to, że trzeba podać pełną szablon do renderowania (np: „Moduł $/$ kontrolera/$ action”)

Mam nadzieję, że będzie Ci zacząć chociaż;)

PS: Odpowiedź wygląda następująco:

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

Doceniam reakcję, ale czuję się jak zepsuta płyta. Jest to pomocne, ale nie odpowiada na moje pytanie. Muszę zwrócić kod HTML w odpowiedzi JSON, która będzie zawierać inne zmienne - potencjalnie wiele widoków. –

+0

@ webjawns.com Mam edited my answer, mam nadzieję, że to cię zacznie. – Sam

+0

IsXmlHttpRequest() można zignorować btw, był tylko dla mnie, aby wyrenderować mój szablon, z którego nazywam ajax-request;) – Sam

-2

Jak zwykle ramowej deweloper bałagan rzeczą AJAX następujące reguły dlaczego proste, jeśli może być skomplikowane Oto proste rozwiązanie w skrypcie kontrolera

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

Działa to również w ZF1 i ZF2. Brak potrzeby podglądu w ogóle

przypadku korzystania z porad ZF2 twórcy

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


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

AJAX dostał null jako odpowiedź przynajmniej w ZF 2.0.0

+0

Potrzebuję * do renderowania skryptu widoku w ramach odpowiedzi Ajax. –

+0

W ten sposób: '{" html ":" Jestem odpowiedzią HTML "}'. –

6

Możesz użyć prostszego sposobu renderowania widoku dla odpowiedzi 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); 
} 

Uwaga przed klasa użycie JsonModel trzeba config View Manager w module.config.php pliku z modułem.

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

to jest praca dla mnie i mam nadzieję, że ci to pomoże.

1

W ZF 3 można osiągnąć ten sam rezultat z tym kodem

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; 
} 
Powiązane problemy