Yii Framework Forum: Is It Possible To Force Cgridview To Load Data Via Ajax Only? - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Is It Possible To Force Cgridview To Load Data Via Ajax Only? Performance optimization Rate Topic: -----

#1 User is offline   EugeneA 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 10
  • Joined: 18-April 12

Posted 15 March 2013 - 06:10 PM

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.
1

#2 User is offline   yiqing95 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 603
  • Joined: 27-December 10
  • Location:china

Posted 15 March 2013 - 07:30 PM

yes you can achieve this !



<?php $this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'msg-grid',
	'dataProvider'=>$model->search(),
	'filter'=>$model,
    'template'=> Yii::app()->request->getIsAjaxRequest()? '{items}': '',
	'columns'=>array(
		'id',
		'sender',
		'recipient',
		'sent',
		'read',
		'subject',
		/*
		'message',
		*/
		array(
			'class'=>'CButtonColumn',
		),
	),
)); ?>
<a href="javascript:;" onclick="lazyLoadGridView()">lazyLoadGridView</a>
    <script type="text/javascript">
        function lazyLoadGridView(){
            $.fn.yiiGridView.update('msg-grid');
        }
    </script>


the key point is this line :
    'template'=> Yii::app()->request->getIsAjaxRequest()? '{items}': '',


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 . :lol:
3

#3 User is offline   mtlife 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 24-April 12

Posted 16 May 2013 - 11:26 AM

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?
0

#4 User is offline   yiqing95 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 603
  • Joined: 27-December 10
  • Location:china

Posted 18 May 2013 - 12:39 PM

View Postmtlife, on 16 May 2013 - 11:26 AM, said:

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)
0

#5 User is offline   yiqing95 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 603
  • Joined: 27-December 10
  • Location:china

Posted 18 May 2013 - 12:49 PM

and another solution i thought is that : use a fake dataProvider

if(Yii::app()->request->getIsAjaxRequest()){
$this->widget('zii.widgets.grid.CGridView', array(
        'id'=>'msg-grid',
        'dataProvider'=> CArrayDataProvider(....),
       ///  'filter'=>$model,
    'template'=> '',
        'columns'=>array(
                 ..
               
        ),
)); 

}else{

$this->widget('zii.widgets.grid.CGridView', array(
        'id'=>'msg-grid',
        'dataProvider'=>$model->search(),
        'filter'=>$model,
    'template'=>'{items}',
        'columns'=>array(
                'id',
                'sender',
                'recipient',
                'sent',
                'read',
                'subject',
                /*
                'message',
                */
                array(
                        'class'=>'CButtonColumn',
                ),
        ),
)); 

}



use a CArrayDataProvider to faking ;D just my thought and have not tested it
0

#6 User is offline   Scott Gardner 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 11
  • Joined: 03-May 13

Posted 07 September 2013 - 02:40 PM

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:

// View
$this->widget('bootstrap.widgets.TbGridView', array(
    ...
    'afterAjaxUpdate'=>'function(id, data) {
        'id'=>'id-of-grid',
        'afterAjaxUpdate'=>'function(id, data) {
        $(\'#floatingCirclesG\').hide();
    }',
    ...


I also wanted to change the "No results found." text dynamically, too. Here's how:

// View
$this->widget('bootstrap.widgets.TbGridView', array(
    ...
    'emptyText'=>Yii::app()->request->isAjaxRequest ? 'No forms awaiting completion.' : 'Loading...',
    ...


Lastly, fwit, note that I'm using a TbGridView from the bootstrap extension, and it works fine.

Hope this helps someone!
1

#7 User is offline   yiqing95 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 603
  • Joined: 27-December 10
  • Location:china

Posted 20 October 2013 - 01:06 PM

// 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 .
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users