Yii2框架自定义GridView链接如何重写ActionColumn

作者:袖梨 2022-11-14

Yii2的GridView链接问题。

 $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yiigridSerialColumn'],
        'id',
        'username',
        'email',
        ['class' => 'yiigridActionColumn'],
    ],
]); ?>



这是一个最简单的默认 GridView,gii生成的就这样,那么问题来了。
如果用户管理不是独立的控制器,而是在user控制器或者是site控制器下,ActionColumn默认链接却是view, update, delete
但是我想要的却是 user-view, user-update, user-delete 这样的链接,然后我修改了下,代码如下。

 $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yiigridSerialColumn'],
        'id',
        'username',
        'email',
        [
            'class' => 'yiigridActionColumn',
            'template' => '{user-view} {user-update} {user-delete}',
        ],
    ],
]); ?>



结果,什么都没了,为什么呢?然后我打开 yiigridActionColumn,看了源码,发现他默认只渲染了view, update, delete
如果 {user-view} 这样的标签在按钮组(buttons[])里不存在,就输出空。


所以我们还要添加按钮才行,然后代码就成了这样。

 $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yiigridSerialColumn'],
        'id',
        'username',
        'email',
        [
            'class' => 'yiigridActionColumn',
            'template' => '{user-view} {user-update} {user-delete}',
            'buttons' = [
                // 下面代码来自于 yiigridActionColumn 简单修改了下
                'user-view' => function ($url, $model, $key) {
                    $options = [
                        'title' => Yii::t('yii', 'View'),
                        'aria-label' => Yii::t('yii', 'View'),
                        'data-pjax' => '0',
                    ];
                    return Html::a('', $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('', $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('', $url, $options);
                },
            ]
        ],
    ],
]); ?>



这样就OK了,但是代码变的超恶心,这不是我想要的,于是我重写了 yiigridActionColumn 增强了 template 的功能。
类似 'template' => '{url-link:type}' 这样的,这里的 url-link 就是你的链接地址,type就是按钮类型,默认的3类按钮还在。

例如:'template' => '{user-view:view} {user-update:update} {user-del:delete}'
这样地址和样式都可以简单搞定,当然你依然可以自定义按钮,方法跟上面那个一样。

 $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yiigridSerialColumn'],
        'id',
        'username',
        'email',
        [
            'class' => 'backendcomponentsActionColumn',
            '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('', $url, $options);
                },
            ]
        ],
    ],
]); ?>



你只要增加一个 diy 类型的按钮就OK了,如果常用的话,你完全可以直接写到 backendcomponentsActionColumn 这里面。
效果如下。



这才是理想的状态,好了,下面给出这个 ActionColumn 代码吧。
我是放在 backendcomponents 目录下,你也可以放在其他你自己喜欢的地方,命名空间改下就OK了。

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);
    }
}



自定义控件之重写GridView

public class GridView : System.Web.UI.WebControls.GridView
{       
    private bool _enableEmptyContentRender = true ;
    /// 
    /// 是否数据为空时显示标题行
    /// 
    public bool EnableEmptyContentRender
    {
        set { _enableEmptyContentRender = value; }
        get { return _enableEmptyContentRender; }
    }
    private string _EmptyDataCellCssClass ;
    /// 
    /// 为空时信息单元格样式类
    /// 
    public string EmptyDataCellCssClass
    {
        set { _EmptyDataCellCssClass = value ; }
        get { return _EmptyDataCellCssClass ; }
    }
    /// 
    /// 为空时输出内容
    /// 
    /// 
    protected virtual void RenderEmptyContent(HtmlTextWriter writer)
    {
        Table t = new Table(); //create a table
        t.CssClass = this.CssClass; //copy all property
        t.GridLines = this.GridLines;
        t.BorderStyle = this.BorderStyle;
        t.BorderWidth = this.BorderWidth;
        t.CellPadding = this.CellPadding;
        t.CellSpacing = this.CellSpacing;
        t.HorizontalAlign = this.HorizontalAlign;
        t.Width = this.Width;
        t.CopyBaseAttributes(this);
        TableRow row = new TableRow();
        t.Rows.Add(row);
        foreach (DataControlField f in this.Columns) //generate table header
        {
            TableCell cell = new TableCell();
            cell.Text = f.HeaderText;
            
            cell.CssClass = "TdHeaderStyle1"; //这里把表头样式写死了
            row.Cells.Add(cell);
        }
        TableRow row2 = new TableRow();
        t.Rows.Add(row2);
        TableCell msgCell = new TableCell();
        msgCell.CssClass = this._EmptyDataCellCssClass;
        if (this.EmptyDataTemplate != null) //the second row, use the template
        {
            this.EmptyDataTemplate.InstantiateIn(msgCell);
        }
        else //the second row, use the EmptyDataText
        {
            msgCell.Text = this.EmptyDataText;
        }
        msgCell.HorizontalAlign = HorizontalAlign.Center;
        msgCell.ColumnSpan = this.Columns.Count;
        row2.Cells.Add(msgCell);
        t.RenderControl(writer);
   }
    protected override void  Render(HtmlTextWriter writer)
    {
       
        if ( _enableEmptyContentRender && ( this.Rows.Count == 0 || this.Rows[0].RowType == DataControlRowType.EmptyDataRow) )
        {
            RenderEmptyContent(writer);
            string mesg = "数据源的记录条数为:" + this.Rows.Count;
            writer.Write(mesg);
            writer.Write("");
        }
        else
        {
            base.Render(writer);
        }
    }
}



yii2.0之GridView自定义按钮和链接用法

本文实例讲述了yii2.0之GridView自定义按钮和链接用法。分享给大家供大家参考。具体实现方法如下:

 $dataProvider,
    //'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yiigridSerialColumn'],
        //显示的字段
        //code的值
        ['attribute'=>'这是测试code','value'=>function(){return 'abc';}],
        'name',
        'population',
       
        ['class' => 'yiigridActionColumn','header' => '操作',],
        [
            'label'=>'更多操作',
            'format'=>'raw',
            'value' => function($data){
                $url = "http://www.baidu.com";
                return Html::a('添加权限组', $url, ['title' => '审核']);
            }
        ]       
    ],
]); ?>



运行效果如下图所示:


相关文章

精彩推荐