yii2 / 在这里有个叫BaseDataProvider的老爹
我們昨天說到了ActiveDataProvider、SqlDataProvider和ArrayDataProvider,從描述中不難發(fā)現(xiàn)這幾個(gè)貨的行為都差不多,因此yii2的開發(fā)者們?yōu)樗鼈冊(cè)O(shè)置了一個(gè)BaseDataProvider的父類,而BaseDataProvider又實(shí)現(xiàn)了一個(gè)叫做DataProviderInterface的接口。
在PHP中,實(shí)現(xiàn)接口的類必須完成接口中聲明的所有函數(shù),當(dāng)我們要看BaseDataProvider中有哪些可用方法的時(shí)候,首先要關(guān)注DataProviderInterface接口。
DataProviderInterface
- prepare
- getCount
- getTotalCount
- getModels
- getKeys
- getSort
- getPagination
以上是DataProviderInterface為我們提供的函數(shù)聲明,也就是說BaseDataProvider類實(shí)現(xiàn)了這些函數(shù),而我們的DataProvider三兄弟也因?yàn)槔^承了BaseDataProvider自然擁有了這些方法。
因此昨天的文章『小談yii2中3個(gè)數(shù)據(jù)提供者及與GridView的搭配使用』中,我們大膽的使用了getCount、getTotalCount、getModels等。
接下來我們先說在BaseDataProvider中來自接口DataProviderInterface的方法。
prepare
數(shù)據(jù)準(zhǔn)備,這是一個(gè)功能性的函數(shù),它負(fù)責(zé)組裝DataProvider中的_models和_keys屬性,我們來大體看一下這個(gè)函數(shù)。
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);} }要研究明白這個(gè)函數(shù),我們首先要了解下 _models 和 _keys 屬性。
- _models 這個(gè)很容易理解,我們通過getModels或GridView得到的對(duì)象集或數(shù)組集合。每一項(xiàng)代表著具體的數(shù)據(jù)。
- _keys 表示每個(gè)數(shù)據(jù)項(xiàng)的唯一鍵,當(dāng)我們使用ActiveDataProvider是就是每條數(shù)據(jù)的主鍵值,而其他兩種DataProvider的是_models數(shù)組的key值。
prepare函數(shù)僅僅在BaseDataProvider類中定義,而每種DataProvider定義了自己的prepareModels和prepareKeys方法,因此我們?cè)诓煌腄ataProvider下調(diào)用prepare得到的是不同的值。
另外prepare也有一個(gè)叫做$forcePrepare的參數(shù),用意很簡(jiǎn)單,是否在_models 和 _keys屬性值已經(jīng)存在的情況下強(qiáng)行刷新,默認(rèn)為false不強(qiáng)行刷新。
getKeys
在介紹prepare的時(shí)候我們看到了prepareModels和prepareKeys,正因?yàn)橛兴鼈兊拇嬖谖覀儾拍苷_通過getModels和getKeys函數(shù)拿到相應(yīng)的數(shù)據(jù)。
我們先來說說getKeys函數(shù),其實(shí)也就是在DataProvider中 $_keys 屬性的內(nèi)容。
這里有一點(diǎn)不同,我們來看下。
ActiveDataProvider
$dataProvider = new ActiveDataProvider(['query' => Blog::find()->select(['title','id']),'pagination' => ['pageSize' => 20,], ]);VarDumper::dump($dataProvider->getKeys(),10,true);我們得到的結(jié)果如下
[0 => 11 => 22 => 33 => 44 => 55 => 9 ]是的,你一定發(fā)現(xiàn)了,_keys是一個(gè)數(shù)組,數(shù)組的key代表每一行數(shù)據(jù)項(xiàng),value值代表對(duì)應(yīng)數(shù)據(jù)的主鍵。
注意:如果你數(shù)據(jù)項(xiàng)中不存在id列,將返回null。比如我們上面代碼的$query是Blog::find()->select(['title'])。而針對(duì)ArrayDataProvider和SqlDataProvider提供者,getKeys得到的數(shù)組就簡(jiǎn)單的多了,數(shù)據(jù)項(xiàng)就是一個(gè)數(shù)組,因此得到的都是如下
[0 => 01 => 12 => 23 => 34 => 45 => 5 ]當(dāng)然你也可以通過setKeys函數(shù)對(duì)這些規(guī)則進(jìn)行重寫,后續(xù)篇章會(huì)講到
getCount & getTotalCount
這是兩個(gè)關(guān)于數(shù)量統(tǒng)計(jì)的函數(shù),用意也及其明白,之所以誕生是因?yàn)镈ataProvider支持分頁功能。
- getCount 當(dāng)前頁面的數(shù)據(jù)項(xiàng)數(shù)量
- getTotalCount 數(shù)據(jù)項(xiàng)總數(shù)量
getSort
得到排序的信息,這個(gè)方法實(shí)現(xiàn)及其簡(jiǎn)單,看一下。
public function getSort() {if ($this->_sort === null) {$this->setSort([]);}return $this->_sort; }從代碼看還是返回了_sort屬性,那么問題就回到setSort方法身上,研究明白如何對(duì)_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.');} }對(duì)于$value的傳遞一共有三種可能
- Array 一個(gè)配置數(shù)組
- Sort 一個(gè)sort對(duì)象
- Bool 一個(gè)布爾型的值
這些我們可以通過新建DataProvider對(duì)象時(shí)候傳入,比如
$dataProvider = new ActiveDataProvider(['query' => Blog::find()->select(['title','id']),'sort'=>false ]);重點(diǎn) 當(dāng)sort為false時(shí)候代表不排序,sort不能為true(會(huì)報(bào)錯(cuò)),當(dāng)我們要排序的時(shí)候應(yīng)該出入配置數(shù)組和sort對(duì)象。
setSort方法會(huì)根據(jù)參數(shù)的類型來進(jìn)行不同的邏輯處理,比如傳遞數(shù)組類型的會(huì)生成一個(gè)一個(gè)Sort對(duì)象并將你的設(shè)置作為新建對(duì)象的參數(shù),當(dāng)然你也可以直接傳入一個(gè)Sort對(duì)象,效果是一樣的。
getPagination
這是一個(gè)重要的函數(shù),它負(fù)責(zé)分頁。
public function getPagination() {if ($this->_pagination === null) {$this->setPagination([]);}return $this->_pagination; }但是不要擔(dān)心,這個(gè)方法和getSort方法的思路完全一致,當(dāng)我們發(fā)現(xiàn)對(duì)象的_pagination不存在時(shí),調(diào)用setPagination對(duì)其進(jìn)行設(shè)置,接下來的代碼你會(huì)非常熟悉。
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.');} }是吧,你是不是發(fā)現(xiàn)和setSort完全一致,接收的函數(shù)也一樣。
小結(jié)
現(xiàn)在你知道DataProvider的運(yùn)行原理以及常用方法了么?接下來我將為你介紹在GridView中是如何對(duì)DataProvider對(duì)象進(jìn)行處理的。
本文來自于 https://nai8.me總結(jié)
以上是生活随笔為你收集整理的yii2 / 在这里有个叫BaseDataProvider的老爹的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++学习-3
- 下一篇: 手把手教你用jQuery实现手动自动轮播