Yii2 GridView默认显示最新年份及点击切换筛选的优化实现
优雅实现Yii2 GridView年份默认筛选与切换功能
这里有一个更贴合Yii2框架设计思路的解决方案,既能满足默认显示最新年份的需求,又能实现优雅的年份切换,还能完美兼容隐藏year列、保留原有URL参数的场景:
1. 优化控制器中默认年份的逻辑
首先改进控制器里获取最大年份的代码,用更高效的聚合查询替代整条记录查询,同时仅在用户未手动选择年份时设置默认值:
public function actionView($id_type) { $searchModel = new MaintenanceSearch(); // 高效获取当前id_type下的最大年份 $maxYear = Maintenance::find() ->where(['id_type' => $id_type]) ->max('year'); // 仅当用户没有传入year参数时,设置默认值为最大年份 if (!Yii::$app->request->get('year')) { $searchModel->year = $maxYear; } // 加载所有查询参数(包括year和其他筛选条件) $dataProvider = $searchModel->search(Yii::$app->request->queryParams); return $this->render('view', [ 'model' => $this->findModel($id_type), 'searchModel' => $searchModel, 'dataProvider' => $dataProvider, 'maxYear' => $maxYear, // 传递给视图用于激活状态判断 'id_type' => $id_type, ]); }
2. 视图中动态生成年份切换链接
在view.php里,利用Yii2的Url::to()方法动态生成年份链接,自动保留当前所有查询参数(包括其他筛选条件),并添加激活状态样式:
<?php // 获取当前页面所有查询参数(比如id_type、其他筛选条件) $currentParams = Yii::$app->request->queryParams; // 从数据库动态获取当前id_type下的所有年份(避免硬编码) $years = Maintenance::find() ->select('year') ->where(['id_type' => $id_type]) ->distinct() ->orderBy('year DESC') ->column(); ?> <!-- 年份切换标签组 --> <div class="year-filter mb-3"> <?php foreach ($years as $year): ?> <?php // 复制当前参数并替换year值 $params = $currentParams; $params['year'] = $year; // 判断当前年份是否为激活状态 $isActive = (isset($currentParams['year']) ? $currentParams['year'] : $maxYear) == $year; $labelClass = $isActive ? 'label-primary' : 'label-default'; ?> <?= Html::a($year, Url::to($params), ['class' => "year label {$labelClass}", 'style' => 'margin-right:5px;']) ?> <?php endforeach; ?> </div>
3. 确保搜索模型正确处理筛选逻辑
在你的MaintenanceSearch模型的search()方法中,确保year字段的筛选逻辑正常工作:
public function search($params) { $query = Maintenance::find(); $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); $this->load($params); // 验证不通过时可选返回全量数据,或根据需求调整 if (!$this->validate()) { return $dataProvider; } // 核心筛选条件:固定id_type,同时根据year参数过滤 $query->andFilterWhere([ 'id_type' => $this->id_type, 'year' => $this->year, // 其他字段筛选条件... ]); // 文本类字段的模糊搜索... // $query->andFilterWhere(['like', 'name', $this->name]); return $dataProvider; }
4. 可选:添加Pjax实现无刷新切换
如果需要无刷新更新GridView,只需要用Pjax包裹年份链接和GridView即可:
<?php Pjax::begin(['id' => 'maintenance-pjax', 'timeout' => 5000]); ?> <!-- 年份切换标签组 --> <div class="year-filter mb-3"> <!-- 上面的年份链接代码 --> </div> <!-- GridView组件 --> <?= GridView::widget([ 'dataProvider' => $dataProvider, 'filterModel' => $searchModel, 'columns' => [ // 你的列配置,不需要显示year列就直接移除该字段 // 'year', 'other_column1', 'other_column2', // 操作列... ], ]); ?> <?php Pjax::end(); ?>
方案优势
- 符合Yii2规范:完全利用框架原生的参数绑定、搜索模型机制,避免自定义JS的冗余逻辑
- 鲁棒性强:隐藏
year列完全不影响功能,自动保留所有原有筛选参数(比如其他查询条件) - 可扩展性好:年份从数据库动态获取,无需硬编码;后续新增筛选条件可自动兼容
- 用户体验佳:默认显示最新年份,点击切换直观,支持无刷新更新(可选)
内容的提问来源于stack exchange,提问作者Moutinho
相关产品推荐
相关产品推荐

