yii2 / 在这里有个叫BaseDataProvider的老爹
我們昨天說到了ActiveDataProvider、SqlDataProvider和ArrayDataProvider,從描述中不難發現這幾個貨的行為都差不多,因此yii2的開發者們為它們設置了一個BaseDataProvider的父類,而BaseDataProvider又實現了一個叫做DataProviderInterface的接口。
在PHP中,實現接口的類必須完成接口中聲明的所有函數,當我們要看BaseDataProvider中有哪些可用方法的時候,首先要關注DataProviderInterface接口。
DataProviderInterface
- prepare
- getCount
- getTotalCount
- getModels
- getKeys
- getSort
- getPagination
以上是DataProviderInterface為我們提供的函數聲明,也就是說BaseDataProvider類實現了這些函數,而我們的DataProvider三兄弟也因為繼承了BaseDataProvider自然擁有了這些方法。
因此昨天的文章『小談yii2中3個數據提供者及與GridView的搭配使用』中,我們大膽的使用了getCount、getTotalCount、getModels等。
接下來我們先說在BaseDataProvider中來自接口DataProviderInterface的方法。
prepare
數據準備,這是一個功能性的函數,它負責組裝DataProvider中的_models和_keys屬性,我們來大體看一下這個函數。
public function prepare($forcePrepare = false){if ($forcePrepare || $this->_models === null) {$this->_models = $this->prepareModels();}if ($forcePrepare || $this->_keys === null) {$this->_keys = $this->prepareKeys($this->_models);} }要研究明白這個函數,我們首先要了解下 _models 和 _keys 屬性。
- _models 這個很容易理解,我們通過getModels或GridView得到的對象集或數組集合。每一項代表著具體的數據。
- _keys 表示每個數據項的唯一鍵,當我們使用ActiveDataProvider是就是每條數據的主鍵值,而其他兩種DataProvider的是_models數組的key值。
prepare函數僅僅在BaseDataProvider類中定義,而每種DataProvider定義了自己的prepareModels和prepareKeys方法,因此我們在不同的DataProvider下調用prepare得到的是不同的值。
另外prepare也有一個叫做$forcePrepare的參數,用意很簡單,是否在_models 和 _keys屬性值已經存在的情況下強行刷新,默認為false不強行刷新。
getKeys
在介紹prepare的時候我們看到了prepareModels和prepareKeys,正因為有它們的存在我們才能正確通過getModels和getKeys函數拿到相應的數據。
我們先來說說getKeys函數,其實也就是在DataProvider中 $_keys 屬性的內容。
這里有一點不同,我們來看下。
ActiveDataProvider
$dataProvider = new ActiveDataProvider(['query' => Blog::find()->select(['title','id']),'pagination' => ['pageSize' => 20,], ]);VarDumper::dump($dataProvider->getKeys(),10,true);我們得到的結果如下
[0 => 11 => 22 => 33 => 44 => 55 => 9 ]是的,你一定發現了,_keys是一個數組,數組的key代表每一行數據項,value值代表對應數據的主鍵。
注意:如果你數據項中不存在id列,將返回null。比如我們上面代碼的$query是Blog::find()->select(['title'])。而針對ArrayDataProvider和SqlDataProvider提供者,getKeys得到的數組就簡單的多了,數據項就是一個數組,因此得到的都是如下
[0 => 01 => 12 => 23 => 34 => 45 => 5 ]當然你也可以通過setKeys函數對這些規則進行重寫,后續篇章會講到
getCount & getTotalCount
這是兩個關于數量統計的函數,用意也及其明白,之所以誕生是因為DataProvider支持分頁功能。
- getCount 當前頁面的數據項數量
- getTotalCount 數據項總數量
getSort
得到排序的信息,這個方法實現及其簡單,看一下。
public function getSort() {if ($this->_sort === null) {$this->setSort([]);}return $this->_sort; }從代碼看還是返回了_sort屬性,那么問題就回到setSort方法身上,研究明白如何對_sort賦值就能知道getSort得到的是什么了~
我們先把代碼貼過來
public function setSort($value){if (is_array($value)) {$config = ['class' => Sort::className()];if ($this->id !== null) {$config['sortParam'] = $this->id . '-sort';}$this->_sort = Yii::createObject(array_merge($config, $value));} elseif ($value instanceof Sort || $value === false) {$this->_sort = $value;} else {throw new InvalidParamException('Only Sort instance, configuration array or false is allowed.');} }對于$value的傳遞一共有三種可能
- Array 一個配置數組
- Sort 一個sort對象
- Bool 一個布爾型的值
這些我們可以通過新建DataProvider對象時候傳入,比如
$dataProvider = new ActiveDataProvider(['query' => Blog::find()->select(['title','id']),'sort'=>false ]);重點 當sort為false時候代表不排序,sort不能為true(會報錯),當我們要排序的時候應該出入配置數組和sort對象。
setSort方法會根據參數的類型來進行不同的邏輯處理,比如傳遞數組類型的會生成一個一個Sort對象并將你的設置作為新建對象的參數,當然你也可以直接傳入一個Sort對象,效果是一樣的。
getPagination
這是一個重要的函數,它負責分頁。
public function getPagination() {if ($this->_pagination === null) {$this->setPagination([]);}return $this->_pagination; }但是不要擔心,這個方法和getSort方法的思路完全一致,當我們發現對象的_pagination不存在時,調用setPagination對其進行設置,接下來的代碼你會非常熟悉。
public function setPagination($value) {if (is_array($value)) {$config = ['class' => Pagination::className()];if ($this->id !== null) {$config['pageParam'] = $this->id . '-page';$config['pageSizeParam'] = $this->id . '-per-page';}$this->_pagination = Yii::createObject(array_merge($config, $value));} elseif ($value instanceof Pagination || $value === false) {$this->_pagination = $value;} else {throw new InvalidParamException('Only Pagination instance, configuration array or false is allowed.');} }是吧,你是不是發現和setSort完全一致,接收的函數也一樣。
小結
現在你知道DataProvider的運行原理以及常用方法了么?接下來我將為你介紹在GridView中是如何對DataProvider對象進行處理的。
本文來自于 https://nai8.me總結
以上是生活随笔為你收集整理的yii2 / 在这里有个叫BaseDataProvider的老爹的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++学习-3
- 下一篇: 手把手教你用jQuery实现手动自动轮播