Yii2 GridView自定义链接之重写 ActionColumn
最近刚开始用yii2,真是超棒的,但是也有许多不足的地方,今天要说的就是GridView链接问题。
1 2 3 4 5 6 7 8 9 10 11 | <?= GridView::widget([ 'dataProvider' => $dataProvider , 'filterModel' => $searchModel , 'columns' => [ [ 'class' => 'yii\grid\SerialColumn' ], 'id' , 'username' , 'email' , [ 'class' => 'yii\grid\ActionColumn' ], ], ]); ?> |
这是一个最简单的默认 GridView,gii生成的就这样,那么问题来了。
如果用户管理不是独立的控制器,而是在user控制器或者是site控制器下,ActionColumn默认链接却是view, update, delete
但是我想要的却是 user-view, user-update, user-delete 这样的链接,然后我修改了下,代码如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?= GridView::widget([ 'dataProvider' => $dataProvider , 'filterModel' => $searchModel , 'columns' => [ [ 'class' => 'yii\grid\SerialColumn' ], 'id' , 'username' , 'email' , [ 'class' => 'yii\grid\ActionColumn' , 'template' => '{user-view} {user-update} {user-delete}' , ], ], ]); ?> |
结果,什么都没了,为什么呢?然后我打开 yii\grid\ActionColumn,看了源码,发现他默认只渲染了view, update, delete
如果 {user-view} 这样的标签在按钮组(buttons[])里不存在,就输出空。
所以我们还要添加按钮才行,然后代码就成了这样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?= GridView::widget([ 'dataProvider' => $dataProvider , 'filterModel' => $searchModel , 'columns' => [ [ 'class' => 'yii\grid\SerialColumn' ], 'id' , 'username' , 'email' , [ 'class' => 'yii\grid\ActionColumn' , 'template' => '{user-view} {user-update} {user-delete}' , 'buttons' = [ // 下面代码来自于 yii\grid\ActionColumn 简单修改了下 'user-view' => function ( $url , $model , $key ) { $options = [ 'title' => Yii::t( 'yii' , 'View' ), 'aria-label' => Yii::t( 'yii' , 'View' ), 'data-pjax' => '0' , ]; return Html::a( '<span class="glyphicon glyphicon-eye-open"></span>' , $url , $options ); }, 'user-update' => function ( $url , $model , $key ) { $options = [ 'title' => Yii::t( 'yii' , 'Update' ), 'aria-label' => Yii::t( 'yii' , 'Update' ), 'data-pjax' => '0' , ]; return Html::a( '<span class="glyphicon glyphicon-pencil"></span>' , $url , $options ); }, 'user-delete' => function ( $url , $model , $key ) { $options = [ 'title' => Yii::t( 'yii' , 'Delete' ), 'aria-label' => Yii::t( 'yii' , 'Delete' ), 'data-confirm' => Yii::t( 'yii' , 'Are you sure you want to delete this item?' ), 'data-method' => 'post' , 'data-pjax' => '0' , ]; return Html::a( '<span class="glyphicon glyphicon-trash"></span>' , $url , $options ); }, ] ], ], ]); ?> |
这样就OK了,但是代码变的超恶心,这不是我想要的,于是我重写了 yii\grid\ActionColumn 增强了 template 的功能。
类似 'template' => '{url-link:type}' 这样的,这里的 url-link 就是你的链接地址,type就是按钮类型,默认的3类按钮还在。
例如:'template' => '{user-view:view} {user-update:update} {user-del:delete}'
这样地址和样式都可以简单搞定,当然你依然可以自定义按钮,方法跟上面那个一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <?= GridView::widget([ 'dataProvider' => $dataProvider , 'filterModel' => $searchModel , 'columns' => [ [ 'class' => 'yii\grid\SerialColumn' ], 'id' , 'username' , 'email' , [ 'class' => 'backend\components\ActionColumn' , 'template' => '{user-view:view} {user-update:update} {user-del:delete} {user-diy-btn:diy}' , 'buttons' => [ // 自定义按钮 'diy' => function ( $url , $model , $key ) { $options = [ 'title' => Yii::t( 'yii' , 'View' ), 'aria-label' => Yii::t( 'yii' , 'View' ), 'data-pjax' => '0' , ]; return Html::a( '<span class="glyphicon glyphicon-refresh"></span>' , $url , $options ); }, ] ], ], ]); ?> |
你只要增加一个 diy 类型的按钮就OK了,如果常用的话,你完全可以直接写到 backend\components\ActionColumn 这里面。
效果如下。
这才是理想的状态,好了,下面给出这个 ActionColumn 代码吧。
我是放在 backend\components 目录下,你也可以放在其他你自己喜欢的地方,命名空间改下就OK了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <?php namespace backend\components; class ActionColumn extends \yii\grid\ActionColumn { public $template = '{:view} {:update} {:delete}' ; /** * 重写了标签渲染方法。 * @param mixed $model * @param mixed $key * @param int $index * @return mixed */ protected function renderDataCellContent( $model , $key , $index ) { return preg_replace_callback( '/\\{([^}]+)\\}/' , function ( $matches ) use ( $model , $key , $index ) { list( $name , $type ) = explode ( ':' , $matches [1]. ':' ); // 得到按钮名和类型 if (!isset( $this ->buttons[ $type ])) { // 如果类型不存在 默认为view $type = 'view' ; } if ( '' == $name ) { // 名称为空,就用类型为名称 $name = $type ; } $url = $this ->createUrl( $name , $model , $key , $index ); return call_user_func( $this ->buttons[ $type ], $url , $model , $key ); }, $this ->template); } } |
好了,今天分享到此结束,如果本文有哪不对,或者你有更好的想法,还望跟帖分享。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
2014-06-03 浅谈 js 字符串之神奇的转义