• Yii2 GridView自定义链接之重写 ActionColumn


    最近刚开始用yii2,真是超棒的,但是也有许多不足的地方,今天要说的就是GridView链接问题。

    <?= GridView::widget([
        'dataProvider' => $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 这样的链接,然后我修改了下,代码如下。

    <?= GridView::widget([
        'dataProvider' => $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[])里不存在,就输出空。

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

    <?= GridView::widget([
        'dataProvider' => $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('<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了,但是代码变的超恶心,这不是我想要的,于是我重写了 yiigridActionColumn 增强了 template 的功能。
    类似 'template' => '{url-link:type}' 这样的,这里的 url-link 就是你的链接地址,type就是按钮类型,默认的3类按钮还在。

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

    <?= GridView::widget([
        'dataProvider' => $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('<span class="glyphicon glyphicon-refresh"></span>', $url, $options);
                    },
                ]
            ],
        ],
    ]); ?>
    

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

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

    <?php
    namespace backendcomponents;
    
    class ActionColumn extends yiigridActionColumn
    {
    
        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);
    
        }
    }
    

    好了,今天分享到此结束,如果本文有哪不对,或者你有更好的想法,还望跟帖分享。。

  • 相关阅读:
    【★】KMP算法完整教程
    【★】KMP算法完整教程
    算法之【牛顿迭代法】
    算法之【牛顿迭代法】
    【★】Web精彩实战之
    【★】Web精彩实战之
    ★RFC标准库_目录链接
    ★RFC标准库_目录链接
    ★教师工资为什么这么低?/整理
    ★教师工资为什么这么低?/整理
  • 原文地址:https://www.cnblogs.com/52cik/p/yii2-ActionColumn.html
Copyright © 2020-2023  润新知