Yii2 GridView过滤器异常:切换单个过滤器影响其他过滤器
Yii2 GridView过滤器联动异常问题解决
问题现象
切换GridView中某一下拉过滤器时,其他未操作的下拉过滤器会自动选中0值,URL会附加所有过滤器参数(未操作的参数为空),最终过滤结果是多个条件的组合,不符合仅应用当前切换过滤器的预期。
原因分析
- 切换过滤器时,GridView会提交所有过滤器参数,未操作的参数值为空字符串
- 搜索模型执行
$this->load($params)时,Yii会将空字符串自动转换为整型0(对应模型属性为整型) andFilterWhere会将0视为有效过滤条件,最终将所有未操作过滤器的0值条件加入查询,导致结果异常
解决方案
方案1:过滤空参数后再加载
在搜索模型的search方法中,先清理掉参数中的空值,仅保留有实际内容的参数,再执行load操作:
修改搜索模型的search方法:
public function search($params) { $query = Model::find()->with('model_b'); if (empty($params['sort'])) { $query->orderBy("group, " . Model::getSortByType() . ', "title"'); } $dataProvider = new ActiveDataProvider([ 'query' => $query, 'sort' => [ 'attributes' => [ 'code', 'title', 'updated_at' ] ] ]); // 过滤空参数,仅保留非空的过滤器参数 if (isset($params['ModelSearch'])) { $params['ModelSearch'] = array_filter( $params['ModelSearch'], function($value) { // 排除空字符串、null值 return $value !== '' && $value !== null; } ); } $this->load($params); if (!$this->validate()) { // uncomment the following line if you do not want to return any records when validation fails // $query->where('0=1'); return $dataProvider; } // grid filtering conditions $query->andFilterWhere([ 'type' => $this->type, 'price_type' => $this->price_type, 'status' => $this->status, 'terms_related' => $this->terms_related, 'required' => $this->required, 'group' => $this->group, ]); $query->andFilterWhere(['ilike', 'title', $this->title]); $query->andFilterWhere(['is_qr' => $this->is_qr]); return $dataProvider; }
方案2:设置搜索模型属性默认值为null
在ModelSearch类中,将布尔/整型过滤器属性的默认值设为null,避免空值被转换为0后被误判为有效条件:
class ModelSearch extends Model { // 其他属性... public $terms_related = null; public $is_qr = null; public $required = null; // ... 其余同类型属性同理设置为null // 验证规则保持不变 public function rules() { return [ // ... 你的规则定义 ]; } }
补充说明
- 方案1是核心解决办法,确保只有用户主动选择的过滤器参数才会被加载到搜索模型中
- 方案2作为辅助,进一步避免空值转换带来的问题
andFilterWhere会自动忽略null值条件,因此只要模型属性为null,对应的过滤条件就不会被加入查询
内容的提问来源于stack exchange,提问作者Tayyab Hussain
相关产品推荐
相关产品推荐

