最近在做控件优化的时候产品提了一个需求,对树的勾选要满足四种勾选方案:
1.点击一次根节点,当根节点和子节点均未选中的情况下,根节点和子节点全都选中。
2.第二次点击根节点,当根节点和部分或全部子节点都选中的情况下,仅选中根节点,子节点不选中。
3.第三次点击根节点,当根节点未选中,且无子节点全未选中的情况下,选中所有子节点,根节点不选中。
4.第四次点击根节点,当根节点未选中,但存在选中的子节点的情况下,根节点和子节点均不选中。
5.点击子节点,可以选中取消。
完整代码:
操作位代码:{
xtype: 'actioncolumn',
width: 48,
text:'选择',
align: 'center',
stopSelection: true,
sortable: false,
menuDisabled: true,
items: [{
width: 13,
height: 13, handler: function (view, rowIdx, colIdx, item, evt) {
var sto = view.getStore();
var rec = sto.getAt(rowIdx);
var check = rec.get('Checked');
if (isNaN(check)) check = 0;
if (check == -1) return;
me.setLoading("loading");
if (check == 1) { //点击的节点是选中状态
check = 0;
me.checkNode(rec, false);
} else { //点击的节点是未选中状态
check = 1;
me.checkNode(rec, true);
}
me.setLoading(false);
}
}]
}核心代码:
checkNode: function (rec, checked) {
var me = this;
var check = 0;
var hasCheckedNode = false; //是否有子节点选中
var hasNodes = false; //是否有子节点
rec.cascade(function (r) { //遍历子节点
var len = r.get('children');
if (len) {
hasNodes = true;
}
if (!r.isLeaf() && !r.isExpanded()) {
r.expand();
}
if (r.get('Checked') == 1 && !len ) { //节点有选中,而且选中的不是父节点本身
hasCheckedNode = true;
} });
if (!checked) {
if (hasCheckedNode && hasNodes) {
//前提:父子节点都选中;效果:父节点选中,子节点不选中。
check = 1; //下级全部取消
rec.cascade(function (r) {
if (r.get('Checked') !== 0)
r.set('Checked', 0);
});
} else if (!hasCheckedNode && hasNodes) {
//前提:父节点选中,子节点未选中;效果:父节点不选中,子节点选中。
check = 0; //下级全部选中
rec.cascade(function (r) {
if (r.get('Checked') !== 1)
r.set('Checked', 1);
}); } else if (!hasCheckedNode && !hasNodes) {
//该节点是无子节点的节点
check = 0; } } else {
if (hasCheckedNode && hasNodes) {
//前提:父节点不选中,子节点选中;效果:父节点都不选中。
check = 0;
//下级全不选中
rec.cascade(function (r) {
if (r.get('Checked') != 0) {
r.set('Checked', 0);
} });
} else if (!hasCheckedNode && hasNodes) {
//前提:父子节点不选中;效果:父子节点都选中。
check = 1;
//下级选中
rec.cascade(function (r) {
if (r.get('Checked') != 1) {
r.set('Checked', 1);
} });
} else if (!hasCheckedNode && !hasNodes) {
//该节点是无子节点的节点
check = 1; } }
rec.set('Checked', check);
} });
Tree.js
核心点分析:
1.首先要确定我们点击的是根节点还是子节点。所以定义了
var hasNodes = false; //是否有子节点
2.要分别控制根节点跟子节点的话,那点击根节点的时候要查看是否有子节点选中,所以继续定义了
var hasCheckedNode = false; //是否有子节点选中
3.再根据点击的该节点的初始状态就可以进行逻辑判断,达到效果。