您的位置:首页 > 编程语言 > PHP开发

[yii2]在这里有个叫BaseDataProvider的老爹

2018-03-16 13:51 197 查看
我们昨天说到了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 => 1
1 => 2
2 => 3
3 => 4
4 => 5
5 => 9
]


是的,你一定发现了,_keys是一个数组,数组的key代表每一行数据项,value值代表对应数据的主键。

注意:如果你数据项中不存在id列,将返回null。比如我们上面代码的$query是Blog::find()->select([‘title’])。

而针对ArrayDataProvider和SqlDataProvider提供者,getKeys得到的数组就简单的多了,数据项就是一个数组,因此得到的都是如下

[
0 => 0
1 => 1
2 => 2
3 => 3
4 => 4
5 => 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) {
$con
4000
fig['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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  yii yii2