Yii2如何为带自定义动态别名的SQL配置DataProvider适配Grid组件
解决方案
方案1:查询时转为数组(最便捷,推荐大部分场景使用)
直接在你的查询构造器后加上asArray()方法,查询结果会以数组形式返回,不需要Model预定义对应别名属性,直接兼容ActiveDataProvider和GridView的所有功能:
// 你的动态构造select的$query,最后加asArray() $query = Stock::find() ->select([ 'Item Id' => 'item_id', 'On Hand' => 'on_hand', 'Amount Produced' => 'initial_on_hand', 'Best By' => 'best_by_date', 'Item Name' => 'item_name', ]) ->from('stock') ->asArray(); $dataProvider = new ActiveDataProvider([ 'query' => $query, 'pagination' => [ 'pageSize' => 20, // 自定义分页大小 ], ]);
GridView中直接写别名作为列名即可:
<?= GridView::widget([ 'dataProvider' => $dataProvider, 'columns' => [ 'Item Id', 'On Hand', 'Amount Produced', 'Best By', 'Item Name', // 其他操作列 ], ]) ?>
方案2:修改对应ActiveRecord模型支持动态属性(适合需要保留AR对象功能的场景)
如果你的业务需要用到ActiveRecord的内置方法、关联查询等功能,不想转为数组,可以在你的Stock模型中添加魔法方法,支持读取动态别名字段:
class Stock extends ActiveRecord { // 原有代码不变,添加以下魔法方法 public function __get($name) { // 优先从查询返回的属性中取值,取不到再走父类逻辑 if (isset($this->attributes[$name])) { return $this->attributes[$name]; } return parent::__get($name); } public function __set($name, $value) { $this->attributes[$name] = $value; } }
修改后不需要改查询逻辑,原来的ActiveDataProvider直接可用,GridView配置和方案1一致。
方案3:使用SqlDataProvider(适合SQL逻辑极其复杂的场景)
如果你的SQL语句是完全动态原生构造,不适合用ActiveQuery拼接,可以直接用Yii2的SqlDataProvider,原生支持分页、排序功能:
// 先统计总条数用于分页 $totalCount = Yii::$app->db->createCommand('SELECT COUNT(*) FROM `stock`')->queryScalar(); // 你的动态构造的原生SQL $rawSql = "SELECT `item_id` AS `Item Id`, `on_hand` AS `On Hand`, `initial_on_hand` AS `Amount Produced`, `best_by_date` AS `Best By`, `item_name` AS `Item Name` FROM `stock`"; $dataProvider = new \yii\data\SqlDataProvider([ 'sql' => $rawSql, 'totalCount' => $totalCount, 'pagination' => [ 'pageSize' => 20, ], 'sort' => [ // 配置允许排序的别名 'attributes' => [ 'Item Id', 'On Hand', 'Amount Produced', 'Best By', 'Item Name', ], ], ]);
GridView配置和前两个方案完全一致。
内容的提问来源于stack exchange,提问作者user1646239
相关产品推荐
相关产品推荐

