fineui是帆软报表和BI产品线所使用的前端框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
9.2 KiB

import { cjkEncodeDO, deepClone, each, extend, isEmpty, isNotNull, isNull, shortcut } from "@/core";
import { TreeView } from "./treeview";
import { TreeRenderPageService } from "./treerender.page.service";
import $ from "jquery";
@shortcut()
export class Asynctree extends TreeView {
static xtype = "bi.async_tree";
_defaultConfig() {
return extend(super._defaultConfig(...arguments), {
showIcon: false,
showLine: true,
});
}
_init() {
super._init(...arguments);
const self = this;
this.service = new TreeRenderPageService({
subNodeListGetter(tId) {
// 获取待检测的子节点列表, ztree并没有获取节点列表dom的API, 此处使用$获取
return $(`#${self.id} #${tId}_ul`);
},
});
}
8 years ago
7 years ago
// 配置属性
_configSetting() {
const o = this.options;
const paras = this.options.paras;
const self = this;
8 years ago
function onClick(event, treeId, treeNode) {
if (treeNode.disabled) {
return false;
}
const zTree = $.fn.zTree.getZTreeObj(treeId);
// 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选
let checked = treeNode.checked;
const status = treeNode.getCheckStatus();
6 years ago
if (status.half === true && status.checked === true) {
checked = false;
}
zTree.checkNode(treeNode, !checked, true, true);
8 years ago
}
function beforeCheck(treeId, treeNode) {
if (treeNode.disabled) {
return false;
}
5 years ago
// 下面主动修改了node的halfCheck属性, 节点属性的判断依赖halfCheck,改之前就获取一下
const status = treeNode.getCheckStatus();
8 years ago
treeNode.halfCheck = false;
if (treeNode.checked === true) {
7 years ago
// 将展开的节点halfCheck设为false,解决展开节点存在halfCheck=true的情况 guy
// 所有的半选状态都需要取消halfCheck=true的情况
function track(children) {
each(children, (i, ch) => {
ch.halfCheck = false;
track(ch.children);
7 years ago
});
8 years ago
}
track(treeNode.children);
const treeObj = $.fn.zTree.getZTreeObj(treeId);
const nodes = treeObj.getSelectedNodes();
each(nodes, (index, node) => {
8 years ago
node.halfCheck = false;
7 years ago
});
8 years ago
}
// 当前点击节点的状态是半选,且为true_part, 则将其改为false_part,使得点击半选后切换到的是全选
6 years ago
if (status.half === true && status.checked === true) {
treeNode.checked = false;
}
8 years ago
}
function beforeExpand(treeId, treeNode) {
8 years ago
self._beforeExpandNode(treeId, treeNode);
8 years ago
}
function onCheck(event, treeId, treeNode) {
if (treeNode.disabled) {
return false;
}
8 years ago
self._selectTreeNode(treeId, treeNode);
}
function onExpand(event, treeId, treeNode) {
8 years ago
treeNode.halfCheck = false;
}
function onCollapse(event, treeId, treeNode) {
8 years ago
treeNode.halfCheck = false;
}
return {
async: {
enable: false, // 很明显这棵树把异步请求关掉了,所有的异步请求都是手动控制的
otherParam: cjkEncodeDO(paras),
},
check: {
enable: true,
},
data: {
key: {
title: "title",
name: "text",
},
simpleData: {
enable: true,
},
},
view: {
showIcon: o.showIcon,
expandSpeed: "",
nameIsHTML: true,
dblClickExpand: false,
showLine: o.showLine,
nodeClasses(treeId, treeNode) {
return { add: [treeNode.iconCls || ""] };
},
},
callback: {
beforeCheck,
onCheck,
beforeExpand,
onExpand,
onCollapse,
onClick,
},
};
}
8 years ago
// 用来更新this.options.paras.selectedValues, 和ztree内部无关
_selectTreeNode(treeId, treeNode) {
const self = this;
let parentValues = deepClone(treeNode.parentValues || self._getParentValues(treeNode));
let name = this._getNodeValue(treeNode);
7 years ago
// var values = parentValues.concat([name]);
8 years ago
if (treeNode.checked === true) {
this._addTreeNode(this.options.paras.selectedValues, parentValues, name, {});
8 years ago
} else {
let tNode = treeNode;
let pNode = this._getTree(this.options.paras.selectedValues, parentValues);
if (isNotNull(pNode[name])) {
8 years ago
delete pNode[name];
}
while (tNode != null && isEmpty(pNode)) {
8 years ago
parentValues = parentValues.slice(0, parentValues.length - 1);
8 years ago
tNode = tNode.getParentNode();
if (tNode != null) {
8 years ago
pNode = this._getTree(this.options.paras.selectedValues, parentValues);
8 years ago
name = this._getNodeValue(tNode);
delete pNode[name];
}
}
this.options.paras.selectedValues = this._getJoinValue();
8 years ago
}
super._selectTreeNode(...arguments);
}
8 years ago
7 years ago
// 展开节点
_beforeExpandNode(treeId, treeNode) {
const self = this,
o = this.options;
function complete(d) {
const nodes = d.items || [];
8 years ago
if (nodes.length > 0) {
callback(self._dealWidthNodes(nodes), !!d.hasNext);
}
}
8 years ago
function callback(nodes, hasNext) {
self.nodes.addNodes(treeNode, nodes);
if (hasNext) {
5 years ago
self.service.pushNodeList(treeNode.tId, getNodes);
} else {
self.service.removeNodeList(treeNode.tId);
8 years ago
}
}
function getNodes(options) {
5 years ago
// console.log(times);
options = options || {};
const parentValues = treeNode.parentValues || self._getParentValues(treeNode);
const op = extend(
{},
o.paras,
{
id: treeNode.id,
times: options.times,
parentValues: parentValues.concat(self._getNodeValue(treeNode)),
checkState: treeNode.getCheckStatus(),
},
options
);
o.itemsCreator(op, complete);
8 years ago
}
// 展开节点会将halfCheck置为false以开启自动计算半选, 所以第一次展开节点的时候需要在置为false之前获取配置
const checkState = treeNode.getCheckStatus();
if (!treeNode.children && !treeNode.requested) {
treeNode.requested = true;
setTimeout(() => {
getNodes({
times: 1,
checkState,
});
7 years ago
}, 17);
8 years ago
}
}
8 years ago
// a,b 两棵树
// a->b b->a 做两次校验, 构造一个校验后的map
// e.g. 以a为基准,如果b没有此节点,则在map中添加。 如b有,且是全选的, 则在map中构造全选(为什么不添加a的值呢? 因为这次是取并集), 如果b中也有和a一样的存值,就递归
_join(valueA, valueB) {
const self = this;
const map = {};
track([], valueA, valueB);
track([], valueB, valueA);
6 years ago
function track(parent, node, compare) {
each(node, (n, item) => {
if (isNull(compare[n])) {
self._addTreeNode(map, parent, n, item);
} else if (isEmpty(compare[n])) {
self._addTreeNode(map, parent, n, item);
} else {
track(parent.concat([n]), node[n], compare[n]);
}
7 years ago
});
8 years ago
}
return map;
}
8 years ago
hasChecked() {
return !isEmpty(this.options.paras.selectedValues) || super.hasChecked(...arguments);
}
8 years ago
_getJoinValue() {
8 years ago
if (!this.nodes) {
return this.options.paras.selectedValues || {};
8 years ago
}
const checkedValues = this._getSelectedValues();
if (isEmpty(checkedValues)) {
return deepClone(this.options.paras.selectedValues);
8 years ago
}
if (isEmpty(this.options.paras.selectedValues)) {
8 years ago
return checkedValues;
}
8 years ago
return this._join(checkedValues, this.options.paras.selectedValues);
}
8 years ago
getValue() {
6 years ago
return this._getJoinValue();
}
6 years ago
7 years ago
// 生成树方法
stroke(config) {
8 years ago
delete this.options.keyword;
this.service.clear();
extend(this.options.paras, config);
const setting = this._configSetting();
8 years ago
this._initTree(setting);
}
}