Browse Source

Merge pull request #1267 in VISUAL/fineui from ~WINDY/fineui:master to master

* commit '462d123ce314aaa78c54ef42b4f0ee6356765062':
  提供获取子节点列表的方法
  按照comment修改
  changelog
  去注释
  update
  树的滚动加载初试
es6
windy 5 years ago
parent
commit
25f4bed318
  1. 7
      changelog.md
  2. 47
      src/base/tree/ztree/asynctree.js
  3. 121
      src/base/tree/ztree/treerender.service.js

7
changelog.md

@ -1,9 +1,12 @@
# 更新日志 # 更新日志
2.0(2020-2) 2.0(2020-03)
- 复选下拉树系列展开节点性能优化
2.0(2020-02)
- 拓展BI.concat,使其可以拼接多个数组 - 拓展BI.concat,使其可以拼接多个数组
- 修复勾选节点不影响父子节点勾选状态的树搜索选中getValue不正常的问题 - 修复勾选节点不影响父子节点勾选状态的树搜索选中getValue不正常的问题
2.0(2020-1) 2.0(2020-01)
- 修复单值系滑块滑动松手后发两次EVENT_CHANGE的问题 - 修复单值系滑块滑动松手后发两次EVENT_CHANGE的问题
2.0(2019-12) 2.0(2019-12)

47
src/base/tree/ztree/asynctree.js

@ -10,6 +10,15 @@ BI.AsyncTree = BI.inherit(BI.TreeView, {
}, },
_init: function () { _init: function () {
BI.AsyncTree.superclass._init.apply(this, arguments); BI.AsyncTree.superclass._init.apply(this, arguments);
var self = this;
this.service = new BI.TreeRenderService({
id: this.id,
container: this.element,
subNodeListGetter: function (tId) {
// 获取待检测的子节点列表, ztree并没有获取节点列表dom的API, 此处使用BI.$获取
return BI.$("#" + self.id + " #" + tId + "_ul");
}
});
}, },
// 配置属性 // 配置属性
@ -138,36 +147,39 @@ BI.AsyncTree = BI.inherit(BI.TreeView, {
// 展开节点 // 展开节点
_beforeExpandNode: function (treeId, treeNode) { _beforeExpandNode: function (treeId, treeNode) {
var self = this, o = this.options; var self = this, o = this.options;
var parentValues = treeNode.parentValues || self._getParentValues(treeNode);
var op = BI.extend({}, o.paras, {
id: treeNode.id,
times: 1,
parentValues: parentValues.concat(this._getNodeValue(treeNode)),
checkState: treeNode.getCheckStatus()
});
var complete = function (d) { var complete = function (d) {
var nodes = d.items || []; var nodes = d.items || [];
if (nodes.length > 0) { if (nodes.length > 0) {
callback(self._dealWidthNodes(nodes), !!d.hasNext); callback(self._dealWidthNodes(nodes), !!d.hasNext);
} }
}; };
var times = 1;
function callback (nodes, hasNext) { function callback(nodes, hasNext) {
if (hasNext) {
self.service.pushNodeList(treeNode.tId, getNodes);
} else {
self.service.removeNodeList(treeNode.tId);
}
// console.log("add nodes");
self.nodes.addNodes(treeNode, nodes); self.nodes.addNodes(treeNode, nodes);
// 展开节点是没有分页的
if (hasNext === true) {
BI.delay(function () {
times++;
op.times = times;
o.itemsCreator(op, complete);
}, 100);
} }
function getNodes(times) {
// console.log(times);
var parentValues = treeNode.parentValues || self._getParentValues(treeNode);
var op = BI.extend({}, o.paras, {
id: treeNode.id,
times: times,
parentValues: parentValues.concat(self._getNodeValue(treeNode)),
checkState: treeNode.getCheckStatus()
});
o.itemsCreator(op, complete);
} }
if (!treeNode.children) { if (!treeNode.children) {
setTimeout(function () { setTimeout(function () {
o.itemsCreator(op, complete); getNodes(1);
}, 17); }, 17);
} }
}, },
@ -221,6 +233,7 @@ BI.AsyncTree = BI.inherit(BI.TreeView, {
// 生成树方法 // 生成树方法
stroke: function (config) { stroke: function (config) {
delete this.options.keyword; delete this.options.keyword;
this.service.clear();
BI.extend(this.options.paras, config); BI.extend(this.options.paras, config);
var setting = this._configSetting(); var setting = this._configSetting();
this._initTree(setting); this._initTree(setting);

121
src/base/tree/ztree/treerender.service.js

@ -0,0 +1,121 @@
/**
* @author windy
* @version 2.0
* Created by windy on 2020/1/8
*/
!(function () {
BI.TreeRenderService = BI.inherit(BI.OB, {
_init: function () {
this.nodeLists = {};
this.id = this.options.id;
// renderService是否已经注册了滚动
this.hasBinded = false;
this.container = this.options.container;
},
_getNodeListBounds: function (tId) {
var nodeList = this.options.subNodeListGetter(tId)[0];
return {
top: nodeList.offsetTop,
left: nodeList.offsetLeft,
width: nodeList.offsetWidth,
height: nodeList.offsetHeight
}
},
_getTreeContainerBounds: function () {
var nodeList = this.container[0];
if (BI.isNotNull(nodeList)) {
return {
top: nodeList.offsetTop + nodeList.scrollTop,
left: nodeList.offsetLeft + nodeList.scrollLeft,
width: nodeList.offsetWidth,
height: nodeList.offsetHeight
};
}
return {};
},
_canNodePopulate: function (tId) {
if (this.nodeLists[tId].locked) {
return false;
}
// 获取ul, 即子节点列表的bounds
// 是否需要继续加载,只需要看子节点列表的下边界与container是否无交集
var bounds = this._getNodeListBounds(tId);
var containerBounds = this._getTreeContainerBounds(tId);
// ul底部是不是漏出来了
if (bounds.top + bounds.height < containerBounds.top + containerBounds.height) {
return true;
}
return false;
},
_isNodeInVisible: function (tId) {
var nodeList = this.options.subNodeListGetter(tId);
return nodeList.length === 0 || nodeList.css("display") === "none";
},
pushNodeList: function (tId, populate) {
var self = this;
if (!BI.has(this.nodeLists, tId)) {
this.nodeLists[tId] = {
populate: BI.debounce(populate, 0),
options: {
times: 1
},
// 在上一次请求返回前, 通过滚动再次触发加载的时候, 不应该认为是下一次分页, 需要等待上次请求返回
// 以保证顺序和请求次数的完整
locked: false
};
} else {
this.nodeLists[tId].locked = false;
}
if(!this.hasBinded) {
// console.log("绑定事件");
this.hasBinded = true;
this.container && this.container.on("scroll", BI.debounce(function () {
self.refreshAllNodes();
}, 30));
}
},
refreshAllNodes: function () {
var self = this;
BI.each(this.nodeLists, function (tId) {
// 不展开的节点就不看了
!self._isNodeInVisible(tId) && self.refreshNodes(tId);
});
},
refreshNodes: function (tId) {
if (this._canNodePopulate(tId)) {
var nodeList = this.nodeLists[tId];
nodeList.options.times++;
nodeList.locked = true;
nodeList.populate(nodeList.options.times);
}
},
removeNodeList: function (tId) {
delete this.nodeLists[tId];
if (BI.size(this.nodeLists) === 0) {
this.clear();
}
},
clear: function () {
var self = this;
BI.each(this.nodeLists, function (tId) {
self.removeNodeList(tId);
});
this.nodeLists = {};
// console.log("解绑事件");
this.container.off("scroll");
this.hasBinded = false;
}
});
})();
Loading…
Cancel
Save