phpjsonviewreturnzend-framework2

zend framework 2, return the rendered contents of a view inside a JSON Model


I am trying to create a JsonModel with an item in the variables 'html' containing the current rendered view. I would like to add this code to an event: rather than this method: How to render ZF2 view within JSON response? which is in the controller, I would like to automate the process by moving it to an Event

I have the strategy in my module.config.php:

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

I have set up a setEventManager in the controller:

    $events->attach(MvcEvent::EVENT_RENDER, function ($e) use ($controller) {
        $controller->setRenderFormat($e);
    }, -20);

Is this the best event to attach it to? would the RENDER_EVENT be better?

Now I would like to change the render of the page based on !$this->getRequest()->isXmlHttpRequest(), (commented out for debug)

public function setRenderFormat($e)
{
    //if(!$this->getRequest()->isXmlHttpRequest())
    //{
    $controller = $e->getTarget();
    $controllerClass = get_class($controller);

    //Get routing info
    $controllerArr = explode('\\', $controllerClass);
    $currentRoute = array(
        'module' =>  strtolower($controllerArr[0]),
        'controller' => strtolower(str_replace("Controller", "", $controllerArr[2])),
        'action' => strtolower($controller->getEvent()->getRouteMatch()->getParam('action'))
    );
    $view_template = implode('/',$currentRoute);

    $viewmodel = new \Zend\View\Model\ViewModel();
    $viewmodel->setTemplate($view_template);
    $htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render($viewmodel, $viewmodel);


    $jsonModel = new JsonModel();
    $jsonModel->setVariables(array(
        'html' => $htmlOutput,
        'jsonVar1' => 'jsonVal2',
        'jsonArray' => array(1,2,3,4,5,6)
    ));

    return $jsonModel;
    //}

}

Strangely, (or not) this code works and produces the $jsonModel, however is doesn't overwite the normal HTML view with the json, but the same code (without the event) in a controller method, overwrites perfectly.

p.s Is there a better method to do the whole concept?

p.p.s how can I obtain the current View Template from within the controller, without resorting to 8 lines of code?

Thanks in advance!

Aborgrove


Solution

  • you are returning the view model from an event I thinks this doesn't have any effect in current viewmanager view model, fetch the current viewmodel from viewmanager and call setTerminal(true). or replace the created jsonmodel using the viewmanager