import { shortcut, extend, emptyFn, each, isKey, UUID, isNotEmptyArray, defaults, createWidget, Tree, nextTick, Selection, Controller, Events, VerticalLayout, AdaptiveLayout, isNull, isArray } from "@/core"; import { Pane, CustomTree, Loader, ButtonTree } from "@/base"; import { BasicTreeNode, BasicTreeItem, TreeExpander } from "@/case"; @shortcut() export class MultiLayerSelectLevelTree extends Pane { static xtype = "bi.multilayer_select_level_tree"; static EVENT_CHANGE = "EVENT_CHANGE"; _defaultConfig() { return extend(super._defaultConfig(...arguments), { baseCls: "bi-multilayer-select-level-tree", isDefaultInit: false, items: [], itemsCreator: emptyFn, keywordGetter: emptyFn, value: "", scrollable: true, }); } _init() { const o = this.options; super._init(...arguments); this.storeValue = o.value; this.initTree(this.options.items); this.check(); } _formatItems(nodes, layer, pNode) { const self = this, o = this.options; const keyword = o.keywordGetter(); each(nodes, (i, node) => { const extend = { isFirstNode: i === 0, isLastNode: i === nodes.length - 1, height: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT, }; node.layer = layer; if (!isKey(node.id)) { node.id = UUID(); } node.keyword = node.keyword || keyword; extend.pNode = pNode; if ( node.isParent === true || node.parent === true || isNotEmptyArray(node.children) ) { extend.type = BasicTreeNode.xtype; extend.selectable = true; defaults(node, extend); self._formatItems(node.children, layer + 1, node); } else { extend.type = BasicTreeItem.xtype; defaults(node, extend); } }); return nodes; } _assertId(sNodes) { each(sNodes, (i, node) => { node.id = node.id || UUID(); }); } initTree(nodes) { const self = this, o = this.options; let hasNext = false; this.empty(); this._assertId(nodes); this.tree = createWidget({ type: CustomTree.xtype, cls: "tree-view display-table", expander: { type: TreeExpander.xtype, selectable: true, isDefaultInit: o.isDefaultInit, el: {}, popup: { type: CustomTree.xtype, }, }, items: this._formatItems(Tree.transformToTreeFormat(nodes), 0), itemsCreator(op, callback) { op.times === 1 && !op.node && nextTick(() => { self.loading(); }); o.itemsCreator(op, ob => { hasNext = ob.hasNext; op.times === 1 && !op.node && self._populate(ob.items); callback( self._formatItems( Tree.transformToTreeFormat(ob.items), op.node ? op.node.layer + 1 : 0, op.node ) ); self.setValue(self.storeValue); op.times === 1 && !op.node && nextTick(() => { self.loaded(); }); }); }, value: o.value, el: { type: Loader.xtype, isDefaultInit: o.itemsCreator !== emptyFn, el: { type: ButtonTree.xtype, chooseType: o.chooseType === Selection.None ? Selection.None : Selection.Default, // 不使用buttontree内部getValue逻辑 behaviors: o.behaviors, layouts: [ { type: VerticalLayout.xtype, } ], }, hasNext() { return hasNext; }, }, }); this.tree.on(Controller.EVENT_CHANGE, function (type, value) { self.fireEvent(Controller.EVENT_CHANGE, arguments); if (type === Events.CLICK) { self.setValue(value); self.fireEvent( MultiLayerSelectLevelTree.EVENT_CHANGE, arguments ); } }); createWidget({ type: AdaptiveLayout.xtype, element: this, scrollable: o.scrollable, items: [this.tree], }); } _populate() { super.populate(...arguments); } populate(nodes) { this._populate(nodes); isNull(nodes) ? this.tree.populate() : this.tree.populate( this._formatItems(Tree.transformToTreeFormat(nodes), 0) ); } setValue(v) { // getValue依赖于storeValue, 那么不选的时候就不要更新storeValue了 if (this.options.chooseType === Selection.None) { } else { this.storeValue = v; this.tree.setValue(v); } } getValue() { return isArray(this.storeValue) ? this.storeValue : isNull(this.storeValue) ? [] : [this.storeValue]; } getAllLeaves() { return this.tree.getAllLeaves(); } getNodeById(id) { return this.tree.getNodeById(id); } getNodeByValue(id) { return this.tree.getNodeByValue(id); } }