Ext.tree.TreeCheckNodeUI 前面是通过这个组件实现的父节点和子节点的级联
但是源码貌似很复杂个人认为,因此不需要通过这个组件实现.
通过以下这两个函数实现类似的功能.
visitAllTreeNodeFun(node, checked);
if (node.parentNode && node.parentNode.getUI().checkbox != null) {
checkParentFun(node.parentNode);
}
但是遇到个新问题,当获取选中的节点时候,只能获取鼠标点击的那个节点,比如点击某一子节点,相关联
的父节点被选中,但是父节点获取不到,级联的相关联节点都获取不到,查询相关资料,改正此处
treeNode.childNodes[i].ui.toggleCheck(checked);//选中
需要先选中,再赋值,才可以获取选中的节点,加上上面的红色那句话就可以了.此时又有个新问题
选中事件发生在子节点,但要通过toggleCheck()改变其父节点未被选中的状态,而一旦改变了父节点未被选中状态为选中状态,就会激发树中的<CheckChange Handler="check(node)" />事件
,每次激发,传入的节点值node一直在改变,陷入一个死循环。
因此要加入suspendEvents()停止监听事件,执行完后再恢复监听
Ext.onReady(function() {
Ext.QuickTips.init();
this.tree = new Ext.tree.TreePanel({
id:'tree',
region: 'center',
autoScroll: true,
animate: true,
width: '280',
collapsible: (this.centerRegion=='center' ? false : true),
split: true,
// tbar: [{xtype:"button",text:"logout",listeners:{ "click":function(){ssd(); }}
// }],
tbar:[' ',
new Ext.form.TextField({
width:150,
emptyText:'快速检索',
enableKeyEvents: true,
listeners:{
keyup:function(node, event) {
findByKeyWordFiler(node, event);
},
}
})
],
enableDD: true,
// checkModel: 'cascade', //对树的级联多选
// onlyLeafCheckable: false,//对树所有结点都可选
containerScroll: true,
border: false,
loader: new Ext.tree.TreeLoader({
url:'/neFunction/test',
//baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI }//解决了获取树节点的级联多选问题
}),
root: new Ext.tree.AsyncTreeNode({
id: "0",
level: "0",
text:"菜单树"
}),
listeners: {
'checkchange': function (node, checked) {
tree.suspendEvents(); //暂停所有监听事件的执行
visitAllTreeNodeFun(node, checked);
if (node.parentNode && node.parentNode.getUI().checkbox != null) {
checkParentFun(node.parentNode);
}
tree.resumeEvents(); //重新开始所有监听事件的执行
}
},
rootVisible: true
});
this.tree.getRootNode().expand();
this.tree.addListener("click",this.ClickNode);
this.contextMenu = new Ext.menu.Menu({
id:"treeContextMenu",
items:[
{
text:"查看",
handler:function() {
Ext.Msg.alert("...",Ext.getCmp('tree').getSelectionModel().getSelectedNode().id);
}
}
]
});
this.tree.on("contextmenu",function(node,e) {
e.preventDefault(); // 阻止弹出默认右键菜单
node.select(); // 选中节点
Ext.getCmp("treeContextMenu").showAt(e.getXY());
});
var timeOutId = null;
var treeFilter = new Ext.tree.TreeFilter(tree, {
clearBlank : true,
autoClear : true
});
// 保存上次隐藏的空节点
var hiddenPkgs = [];
var findByKeyWordFiler = function(node, event) {
clearTimeout(timeOutId);// 清除timeOutId
tree.expandAll();// 展开树节点
// 为了避免重复的访问后台,给服务器造成的压力,采用timeOutId进行控制,如果采用treeFilter也可以造成重复的keyup
timeOutId = setTimeout(function() {
// 获取输入框的值
var text = node.getValue();
// 根据输入制作一个正则表达式,'i'代表不区分大小写
var re = new RegExp(Ext.escapeRe(text), 'i');
// 先要显示上次隐藏掉的节点
Ext.each(hiddenPkgs, function(n) {
n.ui.show();
});
hiddenPkgs = [];
if (text != "") {
treeFilter.filterBy(function(n) {
// 只过滤叶子节点,这样省去枝干被过滤的时候,底下的叶子都无法显示
return !n.isLeaf() || re.test(n.text);
});
// 如果这个节点不是叶子,而且下面没有子节点,就应该隐藏掉
tree.root.cascade(function(n) {
if(n.id!='0'){
if(!n.isLeaf() &&judge(n,re)==false&& !re.test(n.text)){
hiddenPkgs.push(n);
n.ui.hide();
}
}
});
} else {
treeFilter.clear();
return;
}
}, 500);
};
// 过滤不匹配的非叶子节点或者是叶子节点
var judge =function(n,re){
var str=false;
n.cascade(function(n1){
if(n1.isLeaf()){
if(re.test(n1.text)){ str=true;return; }
} else {
if(re.test(n1.text)){ str=true;return; }
}
});
return str;
};
new Ext.Viewport({
renderTo:Ext.getBody(),
layout : 'border',
autoShow:true,
items: [this.tree]
});
});
function ClickNode(node){
console.info(node.attributes.id);
}
/** 父节点的选择 */
function checkParentFun (treeNode) {
var i;
var check = false;
var nocheck = false;
if (treeNode.hasChildNodes()) {
for (i = 0; i < treeNode.childNodes.length; i++) {
if (treeNode.childNodes[i].getUI().checkbox.checked) {
check = true;
} else {
nocheck = true;
}
}
}
if (check == true && nocheck == false) { // 可以全选
treeNode.getUI().checkbox.checked = true;
} else if (check == true && nocheck == true) { // 半选 孩子节点既有选中的也有未选中的 这种情况则父节点还是选中
treeNode.ui.toggleCheck(true);
treeNode.getUI().checkbox.checked = true;
if(treeNode.parentNode&& treeNode.parentNode.getUI().checkbox != null){
checkParentFun(treeNode.parentNode);
}
} else if (check == false && nocheck == true) { // 全不选 孩子节点都是未选中的则父节点取消选中
treeNode.ui.toggleCheck(false);
treeNode.getUI().checkbox.checked = false;
treeNode.collapse();//父节点收缩
if(treeNode.parentNode&& treeNode.parentNode.getUI().checkbox != null){
checkParentFun(treeNode.parentNode);
}
}
};
/** 孩子节点的选择 */
function visitAllTreeNodeFun (treeNode,checked) {
var i;
checked ? treeNode.expand() : treeNode.collapse();//点击某一节点让子节点都展开全部展开
if (treeNode.hasChildNodes()) {
for (i = 0; i < treeNode.childNodes.length; i++) {
if (treeNode.childNodes[i].getUI().checkbox) {
treeNode.childNodes[i].ui.toggleCheck(checked);//选中
treeNode.childNodes[i].getUI().checkbox.checked = checked;//
visitAllTreeNodeFun(treeNode.childNodes[i],checked);
}
}
}
};
/** 根据路径对于节点的选择以及获取选中的节点 */
function ssd(){
tree.expandPath("/0/201/401/511");//
var treeNode = Ext.getCmp("tree").getNodeById("511");
if (treeNode) {
treeNode.getUI().checkbox.checked = true;
}
var checkedNodes = Ext.getCmp("tree").getChecked();
var s = [];
for (var i = 0; i < checkedNodes.length; i++) {
s.push(checkedNodes[i].text);
}
alert(s);
}