UNPKG

element-nice-ui

Version:

A Component Library for Vue.js.

348 lines (282 loc) 8.27 kB
import Node from './node' import { getNodeKey } from './util' export default class TreeStore { constructor(options) { this.currentNode = null this.currentNodeKey = null for (let option in options) { if (options.hasOwnProperty(option)) { this[option] = options[option] } } this.nodesMap = {} this.root = new Node({ data: this.data, store: this }) if (this.lazy && this.load) { const loadFn = this.load loadFn(this.root, (data) => { this.root.doCreateChildren(data) this._initDefaultCheckedNodes() }) } else { this._initDefaultCheckedNodes() } } filter(value) { const filterNodeMethod = this.filterNodeMethod const lazy = this.lazy const traverse = function(node) { const childNodes = node.root ? node.root.childNodes : node.childNodes childNodes.forEach((child) => { child.visible = filterNodeMethod.call(child, value, child.data, child) traverse(child) }) if (!node.visible && childNodes.length) { let allHidden = true allHidden = !childNodes.some((child) => child.visible) if (node.root) { node.root.visible = allHidden === false } else { node.visible = allHidden === false } } if (!value) return if (node.visible && !node.isLeaf && !lazy) node.expand() } traverse(this) } setData(newVal) { const instanceChanged = newVal !== this.root.data if (instanceChanged) { this.root.setData(newVal) this._initDefaultCheckedNodes() } else { this.root.updateChildren() } } getNode(data) { if (data instanceof Node) return data const key = typeof data !== 'object' ? data : getNodeKey(this.key, data) return this.nodesMap[key] || null } insertBefore(data, refData) { const refNode = this.getNode(refData) refNode.parent.insertBefore({ data }, refNode) } insertAfter(data, refData) { const refNode = this.getNode(refData) refNode.parent.insertAfter({ data }, refNode) } remove(data) { const node = this.getNode(data) if (node && node.parent) { if (node === this.currentNode) { this.currentNode = null } node.parent.removeChild(node) } } append(data, parentData) { const parentNode = parentData ? this.getNode(parentData) : this.root if (parentNode) { parentNode.insertChild({ data }) } } _initDefaultCheckedNodes() { const defaultCheckedKeys = this.defaultCheckedKeys || [] const nodesMap = this.nodesMap defaultCheckedKeys.forEach((checkedKey) => { const node = nodesMap[checkedKey] if (node) { node.setChecked(true, !this.checkStrictly) } }) } _initDefaultCheckedNode(node) { const defaultCheckedKeys = this.defaultCheckedKeys || [] if (defaultCheckedKeys.indexOf(node.key) !== -1) { node.setChecked(true, !this.checkStrictly) } } setDefaultCheckedKey(newVal) { if (newVal !== this.defaultCheckedKeys) { this.defaultCheckedKeys = newVal this._initDefaultCheckedNodes() } } registerNode(node) { const key = this.key if (!key || !node || !node.data) return const nodeKey = node.key if (nodeKey !== undefined) this.nodesMap[node.key] = node } deregisterNode(node) { const key = this.key if (!key || !node || !node.data) return node.childNodes.forEach((child) => { this.deregisterNode(child) }) delete this.nodesMap[node.key] } getCheckedNodes(leafOnly = false, includeHalfChecked = false, merge = false) { const checkedNodes = [] const traverse = function(node) { const childNodes = node.root ? node.root.childNodes : node.childNodes childNodes.forEach((child) => { if ( (child.checked || (includeHalfChecked && child.indeterminate)) && (!leafOnly || (leafOnly && child.isLeaf)) && (!merge || (merge && !child.parent.checked)) ) { checkedNodes.push(child.data) } traverse(child) }) } traverse(this) return checkedNodes } getCheckedKeys(leafOnly = false, merge = false) { return this.getCheckedNodes(leafOnly, false, merge).map((data) => (data || {})[this.key]) } getHalfCheckedNodes() { const nodes = [] const traverse = function(node) { const childNodes = node.root ? node.root.childNodes : node.childNodes childNodes.forEach((child) => { if (child.indeterminate) { nodes.push(child.data) } traverse(child) }) } traverse(this) return nodes } getHalfCheckedKeys() { return this.getHalfCheckedNodes().map((data) => (data || {})[this.key]) } _getAllNodes() { const allNodes = [] const nodesMap = this.nodesMap for (let nodeKey in nodesMap) { if (nodesMap.hasOwnProperty(nodeKey)) { allNodes.push(nodesMap[nodeKey]) } } return allNodes } updateChildren(key, data) { const node = this.nodesMap[key] if (!node) return const childNodes = node.childNodes for (let i = childNodes.length - 1; i >= 0; i--) { const child = childNodes[i] this.remove(child.data) } for (let i = 0, j = data.length; i < j; i++) { const child = data[i] this.append(child, node.data) } } _setCheckedKeys(key, leafOnly = false, checkedKeys) { const allNodes = this._getAllNodes().sort((a, b) => b.level - a.level) const cache = Object.create(null) const keys = Object.keys(checkedKeys) allNodes.forEach((node) => node.setChecked(false, false)) for (let i = 0, j = allNodes.length; i < j; i++) { const node = allNodes[i] const nodeKey = node.data[key].toString() let checked = keys.indexOf(nodeKey) > -1 if (!checked) { if (node.checked && !cache[nodeKey]) { node.setChecked(false, false) } continue } let parent = node.parent while (parent && parent.level > 0) { cache[parent.data[key]] = true parent = parent.parent } if (node.isLeaf || this.checkStrictly) { node.setChecked(true, false) continue } node.setChecked(true, true) if (leafOnly) { node.setChecked(false, false) const traverse = function(node) { const childNodes = node.childNodes childNodes.forEach((child) => { if (!child.isLeaf) { child.setChecked(false, false) } traverse(child) }) } traverse(node) } } } setCheckedNodes(array, leafOnly = false) { const key = this.key const checkedKeys = {} array.forEach((item) => { checkedKeys[(item || {})[key]] = true }) this._setCheckedKeys(key, leafOnly, checkedKeys) } setCheckedKeys(keys, leafOnly = false) { this.defaultCheckedKeys = keys const key = this.key const checkedKeys = {} keys.forEach((key) => { checkedKeys[key] = true }) this._setCheckedKeys(key, leafOnly, checkedKeys) } setDefaultExpandedKeys(keys) { keys = keys || [] this.defaultExpandedKeys = keys keys.forEach((key) => { const node = this.getNode(key) if (node) node.expand(null, this.autoExpandParent) }) } setChecked(data, checked, deep) { const node = this.getNode(data) if (node) { node.setChecked(!!checked, deep) } } getCurrentNode() { return this.currentNode } setCurrentNode(currentNode) { const prevCurrentNode = this.currentNode if (prevCurrentNode) { prevCurrentNode.isCurrent = false } this.currentNode = currentNode this.currentNode.isCurrent = true } setUserCurrentNode(node) { const key = node[this.key] const currNode = this.nodesMap[key] this.setCurrentNode(currNode) } setCurrentNodeKey(key) { if (key === null || key === undefined) { this.currentNode && (this.currentNode.isCurrent = false) this.currentNode = null return } const node = this.getNode(key) if (node) { this.setCurrentNode(node) } } }