Is there a way to make a CGridView not load data on the initial rendering of the view it lives on, and instead make it load the first data page with a subsequent AJAX request after the initial page loads?
This is mostly for performance optimization. There is a data model that is rather slow behind that CGridView, and I would like to be able to have the page load in a snappy way, then have the data load up a few seconds later with an AJAX request.
firstly if not ajax request just use a empty template to render a gridView (just render necessary js css file ) then you can use a timer or manually to load the data of that gridView .
I got this working for my view, but unfortunately the query is still executed before the view is loaded, and then with the ajax request the query executes another time. I would like the activedataprovider to not do anything until the page is loaded, does anyone have a solution?
the reason is that in CBaseListView::init method :
public function init()
{
if($this->dataProvider===null)
throw new CException(Yii::t('zii','The "dataProvider" property cannot be empty.'));
$this->dataProvider->getData();
..
}
this->dataProvider->getData() cause the sql executed!
the init method eager load the data !
and in the CBaseListView::run mehod :
public function run()
{
..
$this->renderKeys();
..
}
$this->renderKeys(); do fetch the data again in CGridView you can track the method calling path .
may be this problem can be settled by extend the CGridView Or CListView and rewrite the init method and the run method (just do not invoke these two methods in the extended class when the request is in ajax mode)
Thanks to the helpful suggestions in this thread, on this stackoverflow thread, and from rawtaz in the IRC live chat, I got this working. Here’s my solution:
// Controller, after creating $dataProvider, before calling $this->render...
if (!Yii::app()->request->isAjaxRequest) {
$dataProvider->criteria->addCondition('1 = 0');
}
// View
<script type="text/javascript">
$(window).load(function() {
$('#id-of-grid').yiiGridView('update');
});
</script>
I wanted to put up my own loading spinner. I created one using this site, display it initially, and then hide it:
// Controller, after creating $dataProvider, before calling $this->render...
if (!Yii::app()->request->isAjaxRequest) {
$dataProvider->criteria->addCondition('1 = 0');
}
above code still need to query the database at the first page loading (even it return empty result ) ! so the fake array dataProvider seems still the better one .