所谓的filterModel搜索,其实是 yii\grid\GridView 组件对外开放的一个功能,来满足各位日常开发所需,尽量避免个人再单独花费时间开发。鉴于有些同学基础实在不咋滴,这节课我们就来简单分析下gridview搜索机制的实现,权且当作补充。
搜索机制实现的流程上:根据表单提交,筛选数据。很简单。下面我们来看下yii2又是如何实现的?
先看效果:
通过index.php?r=category/index访问栏目的列表页,看到在每一个表头下面都有一栏搜索框,而我们在input框内输入点内容,鼠标离开或者回车就发现页面刷新了,而且搜出来了我们想要的结果。
接着来看下该效果是如何实现的:
先看前端:
输入框内输入内容有变化且鼠标离开input框页面刷新了,这就说明有change事件在监听input,而后拿到了输入框内的数据向服务端发起了请求,进而筛选出了数据。
右键查看源码,找到yiiGridView代码:1
jQuery('#w0').yiiGridView({"filterUrl":"\/index.php?r=category%2Findex","filterSelector":"#w0-filters input, #w0-filters select"});
通过控制台分析,我们看到“#w0”是当前gridview的id属性值,(在未对gridview指定id的情况下,系统自动生成对应的id属性值)。当然,我们也可以通过gridview的options为gridview设定id属性1
2
3
4
5<?= GridView::widget([
// ...
'options' => ['id' => 'category'],
// ...
?>
此时右键源码,查看的代码是这样的:1
jQuery('#category').yiiGridView({"filterUrl":"\/index.php?r=category%2Findex","filterSelector":"#category-filters input, #category-filters select"});
也就是说yii为当前gridview对象绑定了yiiGridView方法。传递的参数是一个json对象,json对象键值分别是filterUrl和filterSelector, filterSelector即是表头下面的输入框和下拉框,这一点可以通过控制台查看Elements所得。如下图
右键源码,继续查找线索,我们找到 yii.gridView.js 文件,打开该文件后发现了给gridview绑定的yiiGridView方法,我们来看下yiiGridView又是如何实现的?
调用 methods.init方法
=> 为我们传的参数 filterSelector 绑定change方法
=> 调用 methods.applyFilter 方法创建form表单追加到当前gridview并提交表单,提交的url即是我们一开始传进来的 filterUrl
从Js的一系列操作上,我们发现为当前gridview指定一个id是非常有必要的!
再看后端实现:
通过filterUrl我们看到,请求的地址仍然是当前操作。
先不看代码,按照习惯性的理解,如果我们要获取栏目的列表页的数据,是不是应该实例化一个栏目模型,然后接收get参数,根据where条件最后再用all获取数据并以分页的形式进行展示?
实际的实现方法,也是如此!
打开backend\controller\CategoryController.php文件,找到index操作。此处是先实例化的 CategorySearch类,然后调用CategorySearch的search方法,事实并非像我们上面所说,着急的同学估计要说我忽悠了,这是怎么回事?来看下search方法的实现:
1、为search方法传参:
我们看到在index操作中调用search方法时,传递给search了一个参数 Yii::$app->request->queryParams,这个参数其实并无特殊之处,我们通过源码 yii\web\Request的getQueryParams方法得知,Yii::$app->request->queryParams等同于 $_GET。
2、分析下 CategorySearch的search方法
实例化Category模型 (Category::find())
=> 实例化数据模型(new ActiveDataProvider;)
=> 为Category模型属性赋值(load())
=> 调起validate方法对模型的属性值进行规则校验
=> 追加where条件(andFilterWhere())
=> 返回数据模型 (return new ActiveDataProvider)
简直了,一步一个脚印。一些安全机制,包括字段过滤筛选,字段值验证等都帮我们实现好了!一些基础差的同学,应该好好咀嚼一下当前流程的实现,细细品味一下。
回过头来,看index操作拿到数据模型又是如何操作的呢?通过render方法传递给了index视图,然后赋给了 GridView的dataProvider属性!如此,便实现了数据的搜索机制,方便强大!
布置一个简单的小练习,希望有时间的同学可以做一下
假设我们想要在gridview的上面增加一栏对栏目id的搜索,如下图,而不是在gridview列表内显示搜索,怎么实现呢?