Avoiding duplicate script download when using Ajax calls to render different Views

You are viewing revision #3 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.

« previous (#2)

Introduction

I had to partially render two types of views, depending on user selection. Wanted to display a GRID or a LIST style with an event that AJAX'ed new contents and update a layer with them.

Views exposed

The Grid View
Grid View
The List View
List View
If you see the buttons on the right of the box, you will identify those who change from Grid to List and viceversa.

The issue

Until then all was easy, the issue came when both views had to be processed to render the scripts that provide the dynamics of the grid or the list rendered. I couldn't do it on AJAX calls as I realized that every time a request was made and the partial views had its contents processed (review parameters of renderPartial), the scripts where downloaded again and again, making sometimes multiple function binding to the buttons.

The solution

The only way to do it was to register the required scripts of both partial views on the view that will render the buttons that perform AJAX requests. This is how I did it:

// workaround to register required scripts for grid and list
// $view is a variable with selected or primary option
// and _list and _grid where the two partial views to render
$fake = $this->renderPartial(($view==='_grid'?'_list':'_grid'),
                             array('model'=>$model), true, true); 
echo $this->renderPartial($view, array('model'=>$model), true, false);

As you can see, $fake is used to process the partial view required scripts and hold the contents that will not be rendered. After doing this, AJAX calls to the controller can return the contents of views without the need to process its output anymore:

public function actionIndex()
{
      $model = new MyModel('search');
      // style to display?
      $r = Yii::app()->getRequest();
      $view = $r->getParam('style',false)?'_'.$r->getParam('style') : '_grid';
	
      if($r->getIsAjaxRequest())
      {
         // now we render the views without the need to process
         // output anymore 
         $this->renderPartial($view,array('model'=>$model));
         Yii::app()->end();
      }
      $this->render('index', array('model'=>$model,'view'=>$view));
}