小談yii2中3個資料提供者及與GridView的搭配使用

阿北哥ya發表於2018-03-14

你一定對yii2的ActiveDataProvider很熟悉,黃金組合ActiveDataProvider + GridView幫助無數的yii2開發者快速構造出功能強大的表格。

你可知yii2的世界裡還有SqlDataProviderArrayDataProvider兩位大兄弟?接下來我們把這同家三兄弟的用法做一個小教程。

本文並非配置篇,對於三兄弟的配置大全阿北會在《yii2配置詞典》專欄中進行介紹

ActiveDataProvider

最常用的一個,使用ActiveDataProvider將返回一個物件集合,裡面包含了查詢的物件群、分頁資訊等等,一般我們是這樣用的

$query = User::find();
$dataProvider = new ActiveDataProvider([
  'query'=>$query,
  'pagination'=>[
    'pageSize'=>20
  ]
]);
複製程式碼

在ActiveDataProvider中除了query引數都是可選的,比如pagination、sort等。

當你得到了$dataProvider後,可以將其傳給檢視和GridView進行無敵組合,當然也可以使用自身的一些方法,比如

獲得當前頁的所有users

$dataProvider->getModels();//這是一個內含物件的一維陣列
複製程式碼

獲得頁碼資訊

$dataProvider->getTotalCount();// 獲得總頁數
$dataProvider->getCount();// 當前頁碼
$dataProvider->getPagination(); // 內含的Pagination物件
複製程式碼

上面是最常用的,除此之外還提供了比如refresh等方法。

當然我們最常用的還是將ActiveDataProvider傳遞給GridView然後渲染出表格。

use yii\grid\GridView;
<?= GridView::widget([
  'dataProvider' => $dataProvider,
]);?>
複製程式碼

小結 ActiveDataProvider返回的是物件的集合,確切的說是每一個模型(AR),因此模型的關聯特性可以使用,這讓我們可以構造出複雜完整的表格。

SqlDataProvider

和名字一樣,SqlDataProvider接收一個原生的SQL語句並且能生成一個帶有引數的dataProvider,一個月你總會碰到幾次是用QueryBuilder構造不出來的複雜SQL。

用法如下

$totalCount = Yii::$app->db->createCommand('SELECT COUNT(*) FROM user WHERE sex=:sex', ['sex:' => 1])
            ->queryScalar();

$dataProvider = new SqlDataProvider([
    'sql' => 'SELECT * FROM user WHERE sex=:sex',
    'params' => [':sex' => 1],
    'totalCount' => $totalCount,
    //'sort' =>false,//如果為假則刪除排序
    'sort' => [
        'attributes' => [
            'username' => [
                'asc' => ['username' => SORT_ASC],
                'desc' => ['username' => SORT_DESC],
                'default' => SORT_DESC,
                'label' => '使用者名稱',
            ],
            'sex' => [
                'asc' => ['sex' => SORT_ASC],
                'desc' => ['sex' => SORT_DESC],
                'default' => SORT_DESC,
                'label' => '性別',
            ],
            'created_on'
        ],
    ],
    'pagination' => [
        'pageSize' => 10,
    ],
]);

return $dataProvider;
複製程式碼

不要被上面一大堆程式碼嚇到,我只是裝個逼而已,其實SqlDataProvider必填的引數只有一項,就是sql。比如我下面的這段程式碼

$dataProvider = new SqlDataProvider([
    'sql' => 'SELECT * FROM `blog`'
]);
複製程式碼

當然SqlDataProvider也有一些方法,比如getModels、getTotalCount等方法,不同的是這裡面沒有物件了,這裡面是陣列。這很正常,你不在操作AR了,你現在直接在運算元據庫。

而我們在 小談Yii Framework 2.0(yii2)的資料庫層 提到過,AR才是資料表物件導向的歸宿。

所以當你搭配GridView的時候,就要如下寫程式碼了

GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],
        [
            'label' =>"暱稱",
            'attribute' => 'nickname',
            'value'=>function($data){
                return $data["nickname"];
            }
        ],
        'username',
        'sex',
        'created_on',
        ['class' => 'yii\grid\ActionColumn'],
    ],
]); 
複製程式碼

此刻的$data就是我們sql語句查出的一行。

小結 替補ActiveDataProvider,同時也提供給一些喜歡陣列作為結果的小盆友們,無法使用關聯屬性。當然如果你是一個SQL迷,這種方法也許更直接更快速。

ArrayDataProvider

之所以出現了三種資料提供者(DataProvider)主要是因為我們要面對不同的資料來源、一個Query、一條SQL語句,你看,現在使用ArrayDataProvider你可以將一個陣列作為資料來源還。

比如下面的程式碼

$dataProvider = new ArrayDataProvider([
    'allModels' => Blog::find()->asArray()->all(),// 或Blog::find()->all()
    'pagination' => [
        'pageSize' => 1,
    ],
]);
複製程式碼

allModels 是一個必填項,代表資料來源,allModels是一個陣列,但是allModels裡面的元素並不限制,可以陣列或物件,甚至是簡單的資料型別,比如數字和字串。

當然ArrayDataProvider一樣可以和GridView組合,比如

GridView::widget([
    'dataProvider' => $dataProvider
]);
複製程式碼

對於GridView而言,這三種DataProvider沒有區別

小結 給你一堆資料,然後用ArrayDataProvider進行分頁、排序、構造表格!也許有其使用的場景吧,不過我現在還沒遇到。

小結

這篇文章的初衷是為了讓大家知道yii2中一共提供了幾種資料提供者以及其使用方法,具體配置等我們會在其他專欄介紹。

在本文也使用了一些文章

原文連結 https://nai8.me/site/index.html

相關文章