1. 程式人生 > 其它 >Extjs4 Tree Grid 綜合示例(展開、編輯列、獲取資料)

Extjs4 Tree Grid 綜合示例(展開、編輯列、獲取資料)

用json資料模擬後端傳回來的結果,Extjs tree支援兩種型別的結構,一種是帶children屬性的巢狀式的資料,一種是扁平的,每條記錄帶pid的資料,帶pid的新增配置項可以自動解析成樹形結構。

{
  "text": "根目錄",
  "children": [
    {
      "id": "1",
      "name": "基礎設定",
      "children": [
        {
          "id": "1-1",
          "name": "部門檔案",
          "total": 3,
          "children": [
            {
              
"id": "1-1-1", "name": "增加部門", "nd": "1" }, { "id": "1-1-2", "name": "修改部門" } ] }, { "id": "1-2", "name": "客戶檔案", "nd": "2", "total": 1, "children": [ {
"id": "1-2-1", "name": "增加客戶" }, { "id": "1-2-2", "name": "客戶設定" } ] } ] }, { "id": "2", "name": "綜合業務", "children": [ { "id": "2-1", "name": "憑證", "nd": "1",
"total": 3, "children": [ { "id": "2-1-1", "name": "填制憑證" }, { "id": "2-1-2", "name": "憑證稽核" } ] }, { "id": "2-2", "name": "採購", "nd": "3", "total": 1, "children": [ { "id": "2-2-1", "name": "採購訂單" }, { "id": "2-2-2", "name": "採購結算" } ] } ] } ] }

Tree grid程式碼

Ext.require([ 'Ext.form.*', 'Ext.tip.QuickTipManager' ]);

Ext.onReady(function() {

    Ext.define('myTreeModel', {
        extend : 'Ext.data.Model',
        idProperty: 'id',
        fields : [
            {name : 'id'},
            {name : 'name'},
            {name : 'nd'},
            {name : 'total'},
        ]
    });

    // tree元件要求資料的葉子節點必須有leaf=true,此函式遞迴tree資料檢查和自動新增leaf=true
    function recursiveSetLeaf(treeNode) {
        if (treeNode.children) {

            console.log('當前節點有children');
            Ext.each(treeNode.children, function(child){
                recursiveSetLeaf(child);
            });
        } else {
            console.log('當前節點為末級節點');
            treeNode.leaf = true;
        }
    }


    // 建立grid
    var sdPaperRules = Ext.create('Ext.tree.Panel', {
        id : "sdPaperRules",
        store : new Ext.data.TreeStore({
            model: "myTreeModel",
            proxy: {
                type: 'ajax',
                url: '/exam_admin/admin/service/gkpapers_rule/tree_grid_test.json',
                extractResponseData(response) {
                    // 非pid
                    /**
                     * 如果是扁平的帶pid的記錄,可參考
                     * http://t.zoukankan.com/love-omnus-p-4196603.html
                     *
                     */
                    // var json = Ext.loadFilter(Ext.JSON.decode(response.responseText),{parentField : 'pid'});
                    console.log('response', response);
                    var rootNode = Ext.JSON.decode(response.responseText);
                    recursiveSetLeaf(rootNode);
                    response.responseText = Ext.JSON.encode(rootNode);
                    return response
                },
            },
            folderSort: true
        }),// 指定資料來源
        // 可編輯單元格外掛,配置此外掛後就可以在列配置中啟用列的編輯
        plugins: Ext.create('Ext.grid.plugin.CellEditing', {
            clicksToEdit : 1,
        }),
        viewConfig: {
            // 給表格行新增樣式
            getRowClass(record, rowIndex, rowParams, store){
                if (rowIndex % 2 !== 0) {
                    return "treegrid-row-style-even"; // 給偶數行設定樣式
                }
            }
        },
        autoScroll : true,
        bodyStyle : 'overflow-x:auto; overflow-y:auto',
        autoHeight : true,
        autoWidth : true,
        rootVisible: false,
        // border : true,
        columns : [
            {
                xtype : 'treecolumn',
                text : "功能點",
                width : 250,
                dataIndex : 'name',
                headersDisabled : true,
                menuDisabled : true,
                editable: false
            },
            {
                dataIndex: 'nd',
                text: '難度',
                width : 250,
                // flex: 1,
                align: 'left',
                headersDisabled : true,
                menuDisabled : true,
                renderer(value, metaData, record, rowIndex, colIndex, store, view) {
                    if (!value) return;
                    var html = '';
                    html += `<div style="display:flex;justify-content: flex-start;align-items: center;">`;
                    var radioOptions = [{ "value": "1", "label": "簡單" }, { "value": "2", "label": "普通" }, { "value": "3", "label": "困難" }];
                    for (option of radioOptions) {
                        // console.log('option', option);
                        var checked = option.value == value ? `checked='checked'` : '';
                        var name =  "grid_column_radio_" + record.data.id;
                        var domId = 'radio_' + record.data.id + '_' + option.value;
                        html += `<div style="display:flex;justify-content: center;align-items: center;margin-right:16px;">`;
                        html += `    <input id="${domId}" name='${name}' type='radio' ${checked} value='${option.value}'/>`;
                        html += `    <label for="${domId}">&nbsp;${option.label}</label>`;
                        html += `</div>`;
                    }
                    html += `</div>`;
                    return html;
                }

            },
            {
                text : "數量",
                width : 100,
                dataIndex : 'total',
                headersDisabled : true,
                menuDisabled : true,
                border: 1,
                editor : {
                    xtype : 'textfield'
                }
            }
        ],
        listeners: {
            beforeitemcollapse() {
                console.log('beforeitemcollapse');
                return false; // 禁止收縮節點
            },
            itemclick(treePanel, record, rowTag, rowIndex, event) {
                // 處理單選按鈕選擇事件
                var radio = event.getTarget('input[type="radio"]');
                if (radio) {
                    console.log('要更改的nd', radio.value);
                    record.set({nd: radio.value});
                }
            },
            beforeedit(treePanel, cell, events) {
                console.log('record', cell.record.data);
                if (!cell.record.data.nd) { // 如果當前節點沒有難度設定,則禁止編輯
                    return false;
                }
            }
        },
        bbar : Ext.create("Ext.toolbar.Toolbar", {
            items: [
                {
                    xtype: 'button',
                    text: '獲取結果資料',
                    handler() {
                        getTreeGridData(sdPaperRules.getRootNode());
                        // console.log('1:1', sdPaperRules.getView().getCell(1, 1));

                        // Ext.encode(record.data)
                        // 好像grid有個dirty屬性,判斷修改過沒有,可以把有修改的record過濾出來
                    }
                },
                {
                    xtype : 'tbtext',
                    text: 'test...<span style="color:red;">lsdjfoiej</span>'
                }
            ]
        })
    });

    window.getTreeGridData = function(node) {
        // console.log('node', node);
        if (node.data.nd) {
            console.log('nd', node.data.nd)
        }
        if (node.childNodes) {
            for (n of node.childNodes) {
                getTreeGridData(n);
            }
        }
    }
    // 獲得當前選中的tab,下面將向這個tab新增模組元件
    var tab = Ext.getCmp("treeGridTest");

    // 展開所有節點
    sdPaperRules.expandAll();

    // 向tab裡新增一個按鈕
    tab.add(sdPaperRules);


});

由於Extjs的Tree元件和grid結合的話,預設情況資料行沒有樣式,在多列情況下,不易區分當前單元格屬於哪一樣。因此需要新增全域性樣式控制補充效果。

        .treegrid-row-style-even .x-grid-cell {
            border-top: 1px solid #ededed;
            border-bottom: 1px solid #ededed;
            background-color: #fafafa;
        }
        .treegrid-row-style-even:hover .x-grid-cell {
            background-color: #ededed;
        }