yii2 tree manger 結合girdview的使用方法一種變通解決方案

本文網址:http://my.oschina.net/bubifengyun/blog/605908 本文改進版在:https://my.oschina.net/bubifengyun/blog/776979php

第十八章 treeview跟Gridview的結合

1、功能設想

yii2作的網站,一邊是樹形結構treeview,一邊是表格列表gridview,利用kartik的插件,這兩個都比較容易搭建起來。選擇左邊的treeview,根據不一樣的選擇項,girdview顯示對應節點的信息。這個功能具備較好的使用價值。node

2、參考資料

3、完成步驟

總共花了兩週時間才完成,中間查了不少資料,不一一記錄了。因爲時間較長,可能部份內容缺失,若是沒法工做,歡迎在下面留言。整體流程是以下:安裝tree manager的treeview,=》對treeview顯示內容進行改動,=》把顯示內容更改成gridview,=》修復gridview出現的各類問題。git

一、安裝tree manager 和 girdview

composer require kartik-v/yii2-tree-manager "@dev"
composer require kartik-v/yii2-grid "@dev"

二、數據庫的導入

找到./vendor/kartik-v/yii2-tree-manager/schema/tree.sql文件,因爲本人是xampp開發,使用phpmyadmin, 進入到工做用的db_lhpg,點擊導入按鈕,選擇該文件導入便可。導入後,能夠根據本身須要在tbl_tree添加部分項,或者修改部分備註。 最好不要刪除原有的項。我把添加好的tbl_tree改名爲tbl_unit了,沒有作任何添加。github

三、建立模型Model

可使用gii自動生成工具,Model命名空間爲common/models。修改./common/models/Unit.php文件(對應你生成的文件),修改內容以下。web

namespace common\models;

use Yii;

class Tree extends \kartik\tree\models\Tree
{
/*略*/
}

四、建立Module

這部份內容比較多。ajax

  • 建立文件夾modules,mkdir ./frontend/modules
  • 複製模塊內容到modules文件夾,cp -r ./vendor/kartik-v/yii2-tree-manager ./frontend/modules/tree
  • ./frontend/modules/tree文件夾下全部.php文件的命名空間namespace kartik\tree 改成namespace frontend\modules\tree; 包括那些namespace kartik\tree\controllers等相似的命名空間。
  • 修改配置文件./frontend/config/main.php,加入以下內容。
'modules' => [
   'treemanager' =>  [
        'class' => '\frontend\modules\tree\Module',
    ]
]

五、使用TreeView插件

假設現有一個Personinfo,對應有PersoninfoController的動做sql

/**
     * Every User take control of Out in special unit.
     * @return mixed
     */
    public function actionOut()
    {
        $see_unit = Yii::$app->user->identity->see_unit;
        
        // add children and itself.
        $query = Unit::findOne($see_unit)
            ->children()
            ->orWhere(['id' => $see_unit])
            ->addOrderBy('root, lft');
            
        $current_unit = Yii::$app->session->get('current_unit', 0);
        if ($current_unit === 0){
            $current_unit = $see_unit;
        }

        return $this->render('out', [
            'query' => $query,
            'current_unit' => $current_unit,
        ]);
    }

解說:數據庫

  • 網站經過http://localhost/www/wuzhishan/frontend/web/index.php?r=personinfo%2Fout訪問
  • 因爲是針對特定用戶有特定的查看權限,因此首先獲取查看權限$see_unit
  • $query是提供給TreeView使用的變量.
  • children()函數見yii2-nested-sets的說明。
  • $current_unit是當前正在查看的變量。
  • 這裏若是$current_unit不在可查看權限$see_unit的權限範圍內的話,是0或者其餘數值,則只顯示根目錄的數值。
  • 須要特別說明的是Yii::$app->session->get('current_unit', 0);用於每次刷新,把上次點擊的內容複製過來。也就是須要其餘地方設置 Yii::$app->session->set('current_unit', $current_unit);這個在下面說。

下面說渲染的頁面./frontend/views/personinfo/out.php,代碼以下:數組

<?= TreeView::widget([
    'query'             => $query,
    'headingOptions'    => ['label' => '部別'],
    'nodeView'          => '@frontend/views/personinfo/_nodegridview',
    'nodeActions' => [
        Module::NODE_MANAGE => Url::to(['/treemanager/node/my-manage']),
    ],
    'isAdmin'           => false,
    'rootOptions'       => ['label' => '您能夠查看的部別'],
    'displayValue'      => $current_unit,
    'toolbar'           => [
        TreeView::BTN_REFRESH => false,
        TreeView::BTN_CREATE => false,
        TreeView::BTN_CREATE_ROOT => false,
        TreeView::BTN_REMOVE => false,
        TreeView::BTN_SEPARATOR => false,
        TreeView::BTN_MOVE_UP => false,
        TreeView::BTN_MOVE_DOWN => false,
        TreeView::BTN_MOVE_LEFT => false,
        TreeView::BTN_MOVE_RIGHT => false,
        TreeView::BTN_SEPARATOR => false,
	],
]) ?>

解說:bash

  • $query見controller傳過來的變量。
  • 這裏對nodeView從新賦值了。爲@frontend/views/personinfo/_nodegridview,請必定把路徑寫完,不然沒法找到該頁面。
  • nodeActions只修改了NODE_MANAGE,經多輪測試,一直沒有找到好的解決方案,只好修改Module裏源代碼了,這也是把原來Module內置到frontend的緣由。
  • toolbar被禁用了,可是仍是那麼操蛋,必需要一個個的賦值爲false才能夠。
  • 有不懂的請參考該插件的文檔:http://demos.krajee.com/tree-manager

Module::NODE_MANAGE => Url::to(['/treemanager/node/my-manage'])中的my-manage的解說, 在 ./frontend/modules/tree/controllers/NodeController.php文件中, 該動做對應於actionMyManage函數。內容以下。

/**
     * View a tree node via ajax
     *
     * @return redirect to `/personinfo/out`
     */
    public function actionMyManage()
    {
        extract(static::getPostData());
        if (isset($id) && !empty($id)) {
            Yii::$app->session->set('current_unit', $id);
        }
        return $this->redirect(['/personinfo/out']);
    }

解說:

  • 這個是一種折中作法,原本但願Module::NODE_MANAGE => Url::to(['/frontend/personinfo/out'])的,可是各類調試失敗,作了以下折中。 首先讀取$_POST的內容,主要是點擊TreeView樹形結構節點Node得到id,而後刷新網頁['/personinfo/out'], 把得到的id傳遞過去,傳遞方式採用的session方式。

下面把./frontend/views/personinfo/_nodegridview.php的內容貼出來。

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\widgets\Pjax;
use kartik\grid\GridView;
use kartik\tree\TreeView;
use common\models\Personinfo;
use common\models\PersoninfoSearch;
use common\models\Unit;

/* @var $this yii\web\View */
/* @var $model common\models\Personinfo */
/* @var $form yii\widgets\ActiveForm */

Pjax::begin();
// run every key=>value as variant in PHP.
extract($params);

$children = Unit::findOne($node->id)->children()->all();
$selfAndChildrenID = [$node->id];
foreach($children as $child){
    $selfAndChildrenID[] = $child->id;
}

$searchModel = new PersoninfoSearch();
$searchModel->unit_code = $selfAndChildrenID; 
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);

echo GridView::widget([
    'id' => 'admin-gridview-id',
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        [
            'class' => 'kartik\grid\SerialColumn'
        ],
        'name',
        'is_married',
        'can_home_weekend',
        'mil_rank',
        [
            'class' => 'kartik\grid\ActionColumn',
            'template' => '{view}{update}',
        ],
    ],
    'containerOptions' => ['style'=>'overflow: auto'], // only set when $responsive = false
    'toolbar' =>  [
        '{export}',
        '{toggleData}'
    ],
    'pjax' => true,
    'bordered' => true,
    'striped' => false,
    'condensed' => false,
    'responsive' => true,
    'hover' => true,
 //   'floatHeader' => true,
//    'floatHeaderOptions' => ['scrollingTop' => $scrollingTop],
    'showPageSummary' => true,
    'panel' => [
        'type' => GridView::TYPE_PRIMARY
    ],
]);
Pjax::end();

解說:

  • params是經過動做傳過來的一個變量,知道內有一個node就能夠了,nodeUnit的一個實例或者說是一個對象。
  • $searchModel->unit_code = $selfAndChildrenID;設置該語句的時候,其中$selfAndChildrenID是數組array。 須要設置searchPersoninforules的規則,unit_codesafe。Yii2會實現自動搜索全部歸屬這些單位的人員。
  • 其餘解釋見文檔:https://github.com/kartik-v/yii2-grid 及相關說明。

調試發現,每次點擊gridview的排序,都沒有任何東西放在post變量裏,這個問題須要好好解決。

這樣就實現了一邊是樹形結構TreeView,一邊是表格GridView,且GirdView能夠調節改動。能夠根據本身的須要,排序搜索GridView的內容。

4、值得完善之處

在花費兩週的時間才解決這個問題時,設想了不少方案,好比把原做者的這個模塊給肢解了,各自放到frontend裏。 固然最好的方案是把這個模塊留在./vendor文件夾裏,不須要對他作任何改動。只是修改 Module::NODE_MANAGE => Url::to(['/frontend/personinfo/out']),,而後配置一下Controller裏的ActionOut函數。 因爲缺少時間對此進行更深的研究,先留存在這裏。

5、貼一張圖來過過癮。

輸入圖片說明

6、源代碼

網站正在緊鑼密鼓的開發中,後期會開源。

相關文章
相關標籤/搜索