Extjs將列表簡單數據(非樹形json)解析成樹形數據,以簡化樹的應用


在使用Extjs樹控件的時候有個不方便的地方就是不支持簡單的平行數據,如:

[
{"text": "North America","id": "NA","parentId": ""},
{"text": "Unites States","id": "USA","parentId": "NA"},
{"text": "Redwood City","id": "RCI","parentId": "USA"},
{"text": "Frederick, MD","id": "FMD","parentId": "USA"}
]

只支持嵌套的數據,如:

[{
"text": "North America",
"id": "NA",
"parentId": "",
"leaf": false,
"children": [{
"text": "Unites States",
"id": "USA",
"parentId": "NA",
"leaf": false,
"children": [
{
"text": "Redwood City",
"id": "RCI",
"parentId": "USA",
"leaf": true
},
{
"text": "Frederick, MD",
"id": "FMD",
"parentId": "USA",
"leaf": true
}]
}]
}]

我的解決方案是繼承Ext.data.reader.Json來實現的;

源碼如下:

/**
* Created by jiawenjun on 2015/7/29.
* 將列表數據解析成樹形數據,以簡化樹的應用,10萬條數據以內解析速度無壓力:)
* 配置項:
* treeId ID字段名
* treeParentId 父ID字段名(默認值:id)
* allowCheck:true 允許樹支持Checkbox操作的回調函數
* checked(record) 是否選中狀態的回調數據
* dataRootProperty: 'result.content' 數據根
* expandDepth:int 樹節點展開深度
*/
Ext.define('Ext.ux.data.reader.FastTreeReader', {
extend: 'Ext.data.reader.Json',
alias: 'reader.fasttreereader',
dictData:{},myFieldMapping:null,
/*當proxy的類型為memory時*/
readRecords:function(data, readOptions,internalReadOptions){
var treeJson=data;
if(!!this.sourceData===false){
treeJson=this.parse(data);
}
return this.callParent([treeJson, readOptions, internalReadOptions]);
},
/*當proxy的類型為ajax時*/
getResponseData: function (response) {
try {
this.responseData = Ext.decode(response.responseText);

} catch (ex) {
Ext.Logger.warn('無法解析服務器返回的JSON數據!');
return this.createReadError(ex.message);
}
var treeJson=this.parse(this.responseData);
return treeJson;
},
parse:function(json){
var treeJson=this.myGetTreeJson(json);
return treeJson;
},
myGetTreeJson:function(data){
this.sourceData = data;
if (this.dataRootProperty) {
this.extraData(this.dataRootProperty);
}
var dict={},pid=this.treeParentId || 'parentId',id=this.treeId || 'id';
Ext.Array.each(this.sourceData,function(record){
dict[record[id]]=Ext.clone(record);
},this);
Ext.Array.each(this.sourceData,function(record){
var t=dict[record[pid]];
if(t){
if(t.children){
t.children.push(record);
}else{
t.children=[record];
}
}
},this);
this.dictData=dict;
var rootNodes=[];
Ext.Array.each(this.sourceData,function(record){
if(!dict[record[pid]]){
rootNodes.push(record);
}
});
this.rootNodes=rootNodes;
var treeJson = this.getTreeJson();
return treeJson;
},
getTreeFromData: function (arr) {
this.responseData = arr;
this.sourceData = this.responseData;
if (this.dataRootProperty) {
this.extraData(this.dataRootProperty);
}
var treeJson = this.getTreeJson();
return treeJson;
},
myGetIdName: function () {
return this.treeId || 'id';
},
myGetPidName: function () {
return this.treeParentId || 'parentId'
},
getTreeJson: function () {
var me = this,result=[];
var rootNodes=me.rootNodes;
Ext.Array.each(rootNodes,function(record){
record["nodeDepth"]=1;
if (this.hasChildren(record)) {
record.leaf = false;
record.children = this.myRecursive(record);
}
else {
record.leaf = true;
}
if (this.allowCheck) {
var checked=this.getChecked(record);
if(checked===true||checked===false){
record.checked=checked;
}
}
if (this.expandDepth) {
if (record.nodeDepth <= this.expandDepth) {
record.expanded = true;
}
} else {
record.expanded = false;
}
result.push(record);
},this);
return result;
},
/*
* 遞歸函數(解析成樹形數據)
* */
myRecursive: function (parent) {
var result = [];
var childrens = this.getChildrens(parent);
Ext.Array.each(childrens, function (item) {
var record = item;
record.nodeDepth = parent.nodeDepth + 1;
if (this.hasChildren(item)) {
record.leaf = false;
record.children = this.myRecursive(record);
}
else {
record.leaf = true;
}
if (this.allowCheck) {
var checked=this.getChecked(record);
if(checked===true||checked===false){
record.checked=checked;
}
}
if (this.expandDepth) {
if (record.nodeDepth <= this.expandDepth) {
record.expanded = true;
}
} else {
record.expanded = false;
}
result.push(record);
}, this);
return result;
},
/*
* 獲取兒子列表
*/
getChildrens: function (parent) {
var pid=this.treeParentId || 'parentId',id=this.treeId || 'id';
return this.dictData[parent[id]].children;
},
/*
* 是否包含兒子節點
*/
hasChildren: function (parent) {
var pid=this.treeParentId || 'parentId',id=this.treeId || 'id';
return !!(this.dictData[parent[id]].children);
},
/*
*以支持選中狀態的回調數據checked
* */
getChecked: function (record) {
if (Ext.isFunction(this.checked)) {
return this.checked(record);
}
return false;
},
/*
* 提取數據
* */
extraData: function (rootProperty, sourceData) {
var rootPro = rootProperty.split('.');
Ext.Array.each(rootPro, function (item) {
if (!Ext.isEmpty(item)) {
this.sourceData = this.sourceData[item]
}
}, this);
}
});
示例一:
//使用內存數據
Ext.define('EquiTree',{
extend:'Ext.tree.Panel',
xtype:'equitree',
requires:['Ext.ux.data.reader.FastTreeReader'],
rootVisible: false,
useArrows:true,
store:{
type:'tree',
fields:[],
proxy:{
type:'memory',
data:[
{"text": "North America","id": "NA","parentId": ""},
{"text": "Unites States","id": "USA","parentId": "NA"},
{"text": "Redwood City","id": "RCI","parentId": "USA"},
{"text": "Frederick, MD","id": "FMD","parentId": "USA"}
],
reader:{
type:'fasttreereader'
}
}
}
});
//動態加載數據方式:
store.setProxy({type:'memory',
data:data,
reader:{
type:'fasttreereader',
expandDepth:2
}});
store.load();

示例二:
//使用Ajax請求
Ext.define('EquiTree',{
extend:'Ext.tree.Panel',
xtype:'equitree',
requires:['Ext.ux.data.reader.FastTreeReader'],
rootVisible: false,
useArrows:true,
store:{
type:'tree',
fields:[],
proxy:{
type:'ajax',
url:'您的請求地址',
reader:{
type:'fasttreereader',
//其他配置項請參照源碼說明及其父類Ext.data.reader.Json
}
}
}
});

備注:以上代碼在Extjs5.1上測試通過,大家也可以把這個使用FastTreeReader自己封裝一個treestore,以提高開發效率;





免責聲明!

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



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