/* 树形 source: 除delete之外的所有 view: 当前数据视图,用于配合table,tree显示 数据存储是数组,但是可以体现树形逻辑 */ /** @name Edo.data.DataTree @class @typeName datatree @description 树形数据源 @extend Edo.data.DataTable @example */ Edo.data.DataTree = function(data){ Edo.data.DataTree.superclass.constructor.call(this, data); } Edo.data.DataTree.extend(Edo.data.DataTable, { /** @name Edo.data.DataTree#load @function @description 加载数据 @param {Array} tree 树形数据 */ load: function(tree, view){ if(!tree) tree = []; if(!(tree instanceof Array)) tree = [tree]; this.children = tree; this.source = []; var data = []; this._createTable(tree, data); this.source = data; if(!view){ view = []; this._createTree(this.children, -1, 0, view, this.filterFn); } Edo.data.DataTree.superclass.load.call(this, data, view); }, //是不是在本方法内,重新排定table? syncTreeView: function(action, event){ var view = []; this._createTree(this.children, -1, 0, view, this.filterFn); this.refresh(view, action, event); }, //deep深度, stopNode截止的节点, /** @name Edo.data.DataTree#collapse @function @description 收缩节点 @param {Object} node 节点对象 @param {Boolean} deep 是否影响子级 */ collapse: function(node, deep){ node.expanded = false; if(deep){ this.iterateChildren(node, function(o){ o.expanded = false; }); } this.canFire = true; this.syncTreeView('collapse',{record: node}); }, /** @name Edo.data.DataTree#expand @function @description 展开节点 @param {Object} node 节点对象 @param {Boolean} deep 是否展开所有子节点 */ expand: function(node, deep){ node.expanded = true; var p = this.findParent(node); while(p){ p.expanded = true; p = this.findParent(p); } if(deep){ this.iterateChildren(node, function(o){ o.expanded = true; }); } this.canFire = true; this.syncTreeView('expand',{record: node}); }, /** @name Edo.data.DataTree#toggle @function @description 伸展节点 @param {Object} node 节点对象 @param {Boolean} deep 是否影响子级 */ toggle: function(node, deep){ if(node.expanded) this.collapse(node,deep); else this.expand(node,deep); }, /** @name Edo.data.DataTree#add @function @description 增加节点 @param {Object} node 节点对象 @param {Object} parentNode 父节点 */ add: function(node, p){ if(!p) p = this; if(!p.children) p.children = []; return this.insert(p.children.length, node, p); }, /** @name Edo.data.DataTree#addRange @function @description 增加节点 @param {Array} nodes 节点对象 @param {Object} parentNode 父节点 */ addRange: function(nodes, p){ if(!p) p = this; if(!p.children) p.children = []; return this.insertRange(p.children.length, nodes, p); }, /** @name Edo.data.DataTree#insert @function @description 增加节点到索引处 @param {Number} index 索引 @param {Object} node 节点对象 @param {Object} parentNode 父节点 */ insert: function(index, node, p){ this.insertRange(index, [node], p); }, /** @name Edo.data.DataTree#insertRange @function @description 增加节点到索引处 @param {Number} index 索引 @param {Array} nodes 节点对象 @param {Object} parentNode 父节点 */ insertRange: function(index, records, p){ if(!records || !(records instanceof Array)) return; if(!p) p = this; if(!p.children) p.children = []; var cs = p.children; for(var i = 0, len = records.length; i < len; i++){ var r = records[i]; cs.insert(index+i, r); this._doAdd(r); this.iterateChildren(r, function(n){ this._doAdd(n); }, this); } //重新生成表格, 这时候, 这个data应该是source, 没有任何过滤 var data = []; this._createTable(this.children, data); this.source = data; this.syncTreeView('add',{ records: records, index: index, parentNode: p }); this.changed = true; }, /** @name Edo.data.DataTree#remove @function @description 删除节点 @param {Object} node 节点对象 */ remove: function(node){ var p = this.findParent(node); if(p){ p.children.remove(node); this._doRemove(node); var data = []; this._createTable(this.children, data); this.source = data; this.syncTreeView('remove',{ records: [node], parent: p }); this.changed = true; } }, /** @name Edo.data.DataTree#removeAt @function @description 删除节点 @param {Number} index 删除索引号 @param {Object} parentNode 父节点对象 */ removeAt: function(index, p){ if(!p) throw new Error("父节点为空"); var node = p && p.children ? p.children[index] : null; if(node){ this.remove(node, p); } }, /** @name Edo.data.DataTree#removeRange @function @description 删除数据 @param {Array} records 数据对象数组 @params {Object} node 节点 */ removeRange: function(records, node){ if(!records || !(records instanceof Array)) return; records = records.clone(); for(var i=0,l=records.length; i 0; }, //将树形结构数据,转换为表格结构(其实是得到source源数据表格) _createTable: function(tree, data){ //是一个树结构的数组 for(var i=0,l=tree.length; i 0){ this._createTable(cs, data); } } }, //得到树形的view数据视图表格 _createTree: function(tree, pid, depth, data, fn, scope){ if(!fn) fn = this.filterFn; var hasInView = false; //是否有包含在视图内的节点 for(var i=0,l=tree.length; i 0; if(typeof(t.expanded) === 'undefined') t.expanded = true; else t.expanded = !!t.expanded; //__preid, __nextid t.__preid = t.__nextid = null; if(i != 0) t.__preid = tree[i-1].__id; if(i != l-1) t.__nextid = tree[i+1].__id; var next = fn ? fn.call(scope, t, i) : true; //是否继续 var index = data ? data.length : 0; //保留索引 if(next !== false){ //如果next不为false,则先加上了 if(data) data[index] = t; hasInView = true; } var childInView = false; if(t.__hasChildren){ //如果确定是不是收缩的,则传递data, 否则传递null childInView = this._createTree(t.children, t.__id, depth+1, t.expanded !== false ? data : null, fn); } if(childInView && next === false){ //如果next为false,但是子元素内有符合条件的, 则插入 if(data) data.insert(index, t); hasInView = true; } } return hasInView; }, isAncestor: function(p, n){ if(!p || !n) return false; while(n){ n = this.findParent(n); if(n == p) return true; } return false; }, isDisplay: function(record){ var p = this.findParent(record); if(p == this) return true; if(!p.expanded) return false; return this.isDisplay(p); }, /** @name Edo.data.DataTree#getChildren @function @description 获得节点的子节点(或者是深度子节点集合) @param {Object} node 节点对象 @param {Boolean} deep 是否获取深度子节点集合 */ getChildren: function(node, deep){ if(deep){ var children = []; this.iterateChildren(record, function(node){ children.add(node); }); return children; }else{ return node.children; } } }); Edo.data.DataTree.regType('datatree'); //判断n是否是p的子节点 Edo.data.DataTree.isAncestor = function(p, n){ if(!p || !n) return false; var cs = p.children; if(cs){ for(var i=0,l=cs.length; i