Yii2 GridView自定義鏈接之重寫 ActionColumn


最近剛開始用yii2,真是超棒的,但是也有許多不足的地方,今天要說的就是GridView鏈接問題。

<?= 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 這樣的鏈接,然后我修改了下,代碼如下。

<?= 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[])里不存在,就輸出空。

所以我們還要添加按鈕才行,然后代碼就成了這樣。

<?= 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}'
這樣地址和樣式都可以簡單搞定,當然你依然可以自定義按鈕,方法跟上面那個一樣。

<?= 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了。

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

    }
}

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM