mirror of https://github.com/ElemeFE/element
Tree: add check-descendants attribute
parent
54e5cd2340
commit
41c19249ab
|
@ -22,6 +22,8 @@ export const getChildState = node => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const reInitChecked = function(node) {
|
const reInitChecked = function(node) {
|
||||||
|
if (node.childNodes.length === 0) return;
|
||||||
|
|
||||||
const {all, none, half} = getChildState(node.childNodes);
|
const {all, none, half} = getChildState(node.childNodes);
|
||||||
if (all) {
|
if (all) {
|
||||||
node.checked = true;
|
node.checked = true;
|
||||||
|
@ -42,22 +44,6 @@ const reInitChecked = function(node) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const initLazyLoadChild = node => {
|
|
||||||
const childNodes = node.childNodes;
|
|
||||||
if (node.checked) {
|
|
||||||
for (let i = 0, j = childNodes.length; i < j; i++) {
|
|
||||||
const child = childNodes[i];
|
|
||||||
if (!child.disabled) {
|
|
||||||
child.checked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const parent = node.parent;
|
|
||||||
if (!parent || parent.level === 0) return;
|
|
||||||
reInitChecked(parent);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getPropertyFromData = function(node, prop) {
|
const getPropertyFromData = function(node, prop) {
|
||||||
const props = node.store.props;
|
const props = node.store.props;
|
||||||
const data = node.data || {};
|
const data = node.data || {};
|
||||||
|
@ -261,7 +247,11 @@ export default class Node {
|
||||||
if (this.shouldLoadData()) {
|
if (this.shouldLoadData()) {
|
||||||
this.loadData((data) => {
|
this.loadData((data) => {
|
||||||
if (data instanceof Array) {
|
if (data instanceof Array) {
|
||||||
initLazyLoadChild(this);
|
if (this.checked) {
|
||||||
|
this.setChecked(true, true);
|
||||||
|
} else {
|
||||||
|
reInitChecked(this);
|
||||||
|
}
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -300,45 +290,52 @@ export default class Node {
|
||||||
setChecked(value, deep, recursion, passValue) {
|
setChecked(value, deep, recursion, passValue) {
|
||||||
this.indeterminate = value === 'half';
|
this.indeterminate = value === 'half';
|
||||||
this.checked = value === true;
|
this.checked = value === true;
|
||||||
let { all, allWithoutDisable } = getChildState(this.childNodes);
|
|
||||||
|
|
||||||
if (this.childNodes.length && (!all && allWithoutDisable)) {
|
if (this.store.checkStrictly) return;
|
||||||
this.checked = false;
|
|
||||||
value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleDescendants = (lazy) => {
|
if (!(this.shouldLoadData() && !this.store.checkDescendants)) {
|
||||||
if (deep && !lazy) {
|
let { all, allWithoutDisable } = getChildState(this.childNodes);
|
||||||
const childNodes = this.childNodes;
|
|
||||||
for (let i = 0, j = childNodes.length; i < j; i++) {
|
if (!this.isLeaf && (!all && allWithoutDisable)) {
|
||||||
const child = childNodes[i];
|
this.checked = false;
|
||||||
passValue = passValue || value !== false;
|
value = false;
|
||||||
const isCheck = child.disabled ? child.checked : passValue;
|
|
||||||
child.setChecked(isCheck, deep, true, passValue);
|
|
||||||
}
|
|
||||||
const { half, all } = getChildState(childNodes);
|
|
||||||
if (!all) {
|
|
||||||
this.checked = all;
|
|
||||||
this.indeterminate = half;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
if (!this.store.checkStrictly && this.shouldLoadData()) {
|
const handleDescendants = () => {
|
||||||
// Only work on lazy load data.
|
if (deep) {
|
||||||
this.loadData(() => {
|
const childNodes = this.childNodes;
|
||||||
handleDescendants(true);
|
for (let i = 0, j = childNodes.length; i < j; i++) {
|
||||||
}, {
|
const child = childNodes[i];
|
||||||
checked: value !== false
|
passValue = passValue || value !== false;
|
||||||
});
|
const isCheck = child.disabled ? child.checked : passValue;
|
||||||
} else {
|
child.setChecked(isCheck, deep, true, passValue);
|
||||||
handleDescendants();
|
}
|
||||||
|
const { half, all } = getChildState(childNodes);
|
||||||
|
if (!all) {
|
||||||
|
this.checked = all;
|
||||||
|
this.indeterminate = half;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.shouldLoadData()) {
|
||||||
|
// Only work on lazy load data.
|
||||||
|
this.loadData(() => {
|
||||||
|
handleDescendants();
|
||||||
|
reInitChecked(this);
|
||||||
|
}, {
|
||||||
|
checked: value !== false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
handleDescendants();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = this.parent;
|
const parent = this.parent;
|
||||||
if (!parent || parent.level === 0) return;
|
if (!parent || parent.level === 0) return;
|
||||||
|
|
||||||
if (!this.store.checkStrictly && !recursion) {
|
if (!recursion) {
|
||||||
reInitChecked(parent);
|
reInitChecked(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
checkDescendants: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
autoExpandParent: {
|
autoExpandParent: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
@ -180,6 +184,7 @@
|
||||||
load: this.load,
|
load: this.load,
|
||||||
currentNodeKey: this.currentNodeKey,
|
currentNodeKey: this.currentNodeKey,
|
||||||
checkStrictly: this.checkStrictly,
|
checkStrictly: this.checkStrictly,
|
||||||
|
checkDescendants: this.checkDescendants,
|
||||||
defaultCheckedKeys: this.defaultCheckedKeys,
|
defaultCheckedKeys: this.defaultCheckedKeys,
|
||||||
defaultExpandedKeys: this.defaultExpandedKeys,
|
defaultExpandedKeys: this.defaultExpandedKeys,
|
||||||
autoExpandParent: this.autoExpandParent,
|
autoExpandParent: this.autoExpandParent,
|
||||||
|
|
|
@ -522,6 +522,100 @@ describe('Tree', () => {
|
||||||
}, 100);
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('lazy defaultChecked', done => {
|
||||||
|
vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox', {
|
||||||
|
methods: {
|
||||||
|
loadNode(node, resolve) {
|
||||||
|
if (node.level === 0) {
|
||||||
|
return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]);
|
||||||
|
}
|
||||||
|
if (node.level > 4) return resolve([]);
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve([{
|
||||||
|
label: 'zone' + this.count,
|
||||||
|
id: this.count++
|
||||||
|
}, {
|
||||||
|
label: 'zone' + this.count,
|
||||||
|
id: this.count++
|
||||||
|
}]);
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const tree = vm.$children[0];
|
||||||
|
const firstNode = document.querySelector('.el-tree-node__content');
|
||||||
|
const initStatus = firstNode.querySelector('.is-indeterminate');
|
||||||
|
expect(initStatus).to.equal(null);
|
||||||
|
tree.store.setCheckedKeys([3]);
|
||||||
|
firstNode.querySelector('.el-tree-node__expand-icon').click();
|
||||||
|
setTimeout(() => {
|
||||||
|
const clickStatus = firstNode.querySelector('.is-indeterminate');
|
||||||
|
expect(clickStatus).to.not.equal(null);
|
||||||
|
const child = document.querySelectorAll('.el-tree-node__content')[1];
|
||||||
|
expect(child.querySelector('input').checked).to.equal(true);
|
||||||
|
done();
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('lazy expandOnChecked', done => {
|
||||||
|
vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox check-descendants', {
|
||||||
|
methods: {
|
||||||
|
loadNode(node, resolve) {
|
||||||
|
if (node.level === 0) {
|
||||||
|
return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]);
|
||||||
|
}
|
||||||
|
if (node.level > 4) return resolve([]);
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve([{
|
||||||
|
label: 'zone' + this.count,
|
||||||
|
id: this.count++
|
||||||
|
}, {
|
||||||
|
label: 'zone' + this.count,
|
||||||
|
id: this.count++
|
||||||
|
}]);
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const tree = vm.$children[0];
|
||||||
|
tree.store.setCheckedKeys([1]);
|
||||||
|
setTimeout(() => {
|
||||||
|
const id5 = document.querySelectorAll('.el-tree-node__content')[3];
|
||||||
|
expect(id5.querySelector('input').checked).to.equal(true);
|
||||||
|
done();
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('lazy without expandOnChecked', done => {
|
||||||
|
vm = getTreeVm(':props="defaultProps" node-key="id" lazy :load="loadNode" show-checkbox', {
|
||||||
|
methods: {
|
||||||
|
loadNode(node, resolve) {
|
||||||
|
if (node.level === 0) {
|
||||||
|
return resolve([{ label: 'region1', id: this.count++ }, { label: 'region2', id: this.count++ }]);
|
||||||
|
}
|
||||||
|
if (node.level > 4) return resolve([]);
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve([{
|
||||||
|
label: 'zone' + this.count,
|
||||||
|
id: this.count++
|
||||||
|
}, {
|
||||||
|
label: 'zone' + this.count,
|
||||||
|
id: this.count++
|
||||||
|
}]);
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const tree = vm.$children[0];
|
||||||
|
tree.store.setCheckedKeys([1]);
|
||||||
|
setTimeout(() => {
|
||||||
|
const nodes = document.querySelectorAll('.el-tree-node__content');
|
||||||
|
expect(nodes[0].querySelector('input').checked).to.equal(true);
|
||||||
|
expect(nodes.length).to.equal(2);
|
||||||
|
done();
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
it('accordion', done => {
|
it('accordion', done => {
|
||||||
vm = getTreeVm(':props="defaultProps" accordion');
|
vm = getTreeVm(':props="defaultProps" accordion');
|
||||||
const firstNode = vm.$el.querySelector('.el-tree-node__content');
|
const firstNode = vm.$el.querySelector('.el-tree-node__content');
|
||||||
|
|
Loading…
Reference in New Issue