Data providers are used to encapsulate common data model operations such as sorting, pagination, and querying. They are used with grids and lists extensively. Because both widgets and providers are standardized, you can display the same data using different widgets and you can get data for a widget from various providers. Switching providers and widgets is relatively transparent.
Currently CActiveDataProvider
, CArrayDataProvider
, and CSqlDataProvider
are implemented to get data from Active Record models, arrays, and SQL queries respectively. Let's try all these providers to fill a grid with data.
yiic webapp
as described in the official guide.protected/config/main.php
.film
table.protected/views/grid/index.php
:<?php $this->widget('zii.widgets.grid.CGridView', array('dataProvider' => $dataProvider, ))?>
protected/controllers/GridController.php
:<?php class GridController extends Controller { public function actionAR() { $dataProvider = new CActiveDataProvider('Film', array( 'pagination'=>array( 'pageSize'=>10, ), 'sort'=>array( 'defaultOrder'=> array('title'=> CSort::SORT_ASC), ) )); $this->render('index', array( 'dataProvider' => $dataProvider, )); } public function actionArray() { $yiiDevelopers = array( array( 'name'=>'Qiang Xue', 'id'=>'2', 'forumName'=>'qiang', 'memberSince'=>'Jan 2008', 'location'=>'Washington DC, USA', 'duty'=>'founder and project lead', 'active'=>true, ), array( 'name'=>'Wei Zhuo', 'id'=>'3', 'forumName'=>'wei', 'memberSince'=>'Jan 2008', 'location'=>'Sydney, Australia', 'duty'=>'project site maintenance and development', 'active'=>true, ), array( 'name'=>'Sebastián Thierer', 'id'=>'54', 'forumName'=>'sebas', 'memberSince'=>'Sep 2009', 'location'=>'Argentina', 'duty'=>'component development', 'active'=>true, ), array( 'name'=>'Alexander Makarov', 'id'=>'415', 'forumName'=>'samdark', 'memberSince'=>'Mar 2010', 'location'=>'Russia', 'duty'=>'core framework development', 'active'=>true, ), array( 'name'=>'Maurizio Domba', 'id'=>'2650', 'forumName'=>'mdomba', 'memberSince'=>'Aug 2010', 'location'=>'Croatia', 'duty'=>'core framework development', 'active'=>true, ), array( 'name'=>'Carsten Brandt', 'id'=>'5951', 'forumName'=>'CeBe', 'memberSince'=>'Aug 2012', 'location'=>'Berlin, Germany', 'duty'=>'core framework development', 'active'=>true, ), array( 'name'=>'Y!!', 'id'=>'1644', 'forumName'=>'Y!!', 'memberSince'=>'Aug 2010', 'location'=>'Germany', 'duty'=>'core framework development', 'active'=>false, ), array( 'name'=>'Jeffrey Winesett', 'id'=>'15', 'forumName'=>'jefftulsa', 'memberSince'=>'Sep 2010', 'location'=>'Austin, TX, USA', 'duty'=>'documentation and marketing', 'active'=>true, ), array( 'name'=>'Jonah Turnquist', 'id'=>'127', 'forumName'=>'jonah', 'memberSince'=>'Sep 2009 - Aug 2010', 'location'=>'California, US', 'duty'=>'component development', 'active'=>false, ), array( 'name'=>'István Beregszászi', 'id'=>'1286', 'forumName'=>'pestaa', 'memberSince'=>'Sep 2009 - Mar 2010', 'location'=>'Hungary', 'duty'=>'core framework development', 'active'=>false, ), ); $dataProvider = new CArrayDataProvider($yiiDevelopers, array( 'sort'=>array( 'attributes'=>array('name', 'id', 'active'), 'defaultOrder'=>array('active' => CSort::SORT_DESC, 'name' => CSort::SORT_ASC), ), 'pagination'=>array( 'pageSize'=>10, ), )); $this->render('index', array( 'dataProvider' => $dataProvider, )); } public function actionSQL() { $count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM film')->queryScalar(); $sql='SELECT * FROM film'; $dataProvider=new CSqlDataProvider($sql, array( 'keyField'=>'film_id', 'totalItemCount'=>$count, 'sort'=>array( 'attributes'=>array('title'), 'defaultOrder'=>array('title' => CSort::SORT_ASC), ), 'pagination'=>array( 'pageSize'=>10, ), )); $this->render('index', array( 'dataProvider' => $dataProvider, )); } }
grid/aR
, grid/array
, and grid/sql
actions and try using the grids.The view is pretty simple and stays the same for all data providers. We are calling the grid widget and passing the data provider instance to it.
Let's review the actions one by one starting with actionAR
:
$dataProvider = new CActiveDataProvider('Film', array( 'pagination'=>array( 'pageSize'=>10, ), 'sort'=>array( 'defaultOrder'=>array('title'=>false), ) ));
CActiveDataProvider
works with AR models. The model class is passed as a first argument of the class constructor. The second argument is an array that defines class public properties. In the previous code, we are setting the pagination to 10
items per page and default sorting by title
.
In actionArray
we are using CArrayDataProvider
that can consume any array.
$dataProvider = new CArrayDataProvider($yiiDevelopers, array( 'sort'=>array( 'attributes'=>array('name', 'id', 'active'), 'defaultOrder'=>array('active' => true, 'name' => false), ), 'pagination'=>array( 'pageSize'=>10, ), ));
The first argument accepts an associative array where keys are column names and values are corresponding values. The second argument accepts an array with the same options as in the CActiveDataProvider
case.
In actionSQL
, we are using CSqlDataProvider
that consumes the SQL query and modifies it automatically allowing pagination. The first argument accepts a string with SQL and the second argument with data provider parameters. This time we need to supply calculateTotalItemCount
with the total count of records manually. For this purpose we need to execute the extra SQL query manually. Also, we need to define keyField
since the primary key of this table is not id
but film_id
.
To sum up, all data providers accept the following properties:
You can use data providers without any special widgets. Replace the contents of protected/views/grid/index.php
with the following:
<?php foreach($dataProvider->data as $film):?> <?php echo $film['title'].'<br />'?> <?php endforeach?> <?php $this->widget('CLinkPager',array('pages'=>$dataProvider->pagination))?>
To learn more about data providers refer to the following API pages:
3.145.42.94