Extjs4 Tree Grid 綜合示例(展開、編輯列、獲取資料)
阿新 • • 發佈:2022-12-10
用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}"> ${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; }