树的刷新常常是整颗树全部节点刷新,但有些时候我们需要只刷新某一个节点下的数据,方法很简单,在异步树中我们不难发现,第一次展开一个节点的时候是向后台获取数据的,第二次展开就不会再获取,因方法如下处理:
Ext.applyIf(Ext.data.Model.prototype,{ /* * 重载 */ reload:function(){ var me=this; me.set('loaded', false); me.set('expanded',false); me.expand(); }, /* * 添加新节点时重载 */ loadNewNode:function(){ var me=this; me.set("leaf",false); me.reload(); } });
/* * 级选 */ cascadeCheck:function(checked){ var me=this; me.childCheck(checked); me.parentCheck(checked); }, /* * 级选并展开子节点 */ cascadeCheckExpand:function(checked){ var me=this; me.childCheckExpand(checked); me.parentCheck(checked); }, /* * 级选子节点 */ childCheck:function(checked){ var me=this; me.cascadeBy(function(child) { child.set('checked', checked); }); }, /* * 级选子节点并展开 */ childCheckExpand:function(checked){ var me=this; me.expand(false,function(childs){ if(childs!=null){ for(var i=0;i<childs.length;i++){ var child=childs[i]; child.set('checked', checked); child.childCheckExpand(checked); } } }); }, /* * 级选父节点 */ parentCheck:function(checked){ var me=this; var parentNode = me.parentNode; if (parentNode != null) { if((checked&&!parentNode.get('checked'))||(!checked&&!parentNode.hasCheckedChild())){ parentNode.set('checked', checked); parentNode.parentCheck(checked); } } }, /* * 是否存在已选择子节点 */ hasCheckedChild:function(){ var node = this; var value=false; node.eachChild(function(child) { if (child.get('checked')) { value=true; return false; } }); return value; }
还有一种情况可能大家都有经历,就是级选被包含的节点,比如商品类别,每个商家拥有一套完整的商品类别,这个时候当我第二次修改商家的商品类别时,系统肯定要先把已经保存到该商家的节点勾选出来,这里有两个要求,一是勾选出已经存储的节点,二是树不能全部展开,可以想像,总的商品类别树是很庞大的,不可能把全部节点展开再级选包含的节点,所以改造如下:
/* * 级选并展开被包含节点 */ containCheckChildExpand:function(cons,id){ var me=this; me.expand(false,function(childs){ if(childs!=null){ for(var i=0;i<childs.length;i++){ var child=childs[i]; if (cons.contain(child.get(id))) { child.set('checked', true); child.containCheckChildExpand(cons,id); }else if(child.get('checked')){ child.set('checked', false); child.childCheck(false); } } } }); }, /* * 级选被包含节点并展开全部 */ containCheckChildAllExpand:function(cons,id){ var me=this; me.expand(false,function(childs){ if(childs!=null){ for(var i=0;i<childs.length;i++){ var child=childs[i]; if (cons.contain(child.get(id))) { child.set('checked', true); }else if(child.get('checked')){ child.set('checked', false); child.childCheck(false); } child.containCheckChildAllExpand(cons,id); } } }); }, /* * 级选被包含节点(同步树) */ containCheckChild:function(cons,id){ var me=this; me.cascadeBy(function(child) { if (cons.contain(child.get(id))) { child.set('checked', true); }else{ child.set('checked', false); } }); }, /* * 级选被包含子节点 */ selectContainChildren:function(res,id){ var cons = new Array(); Ext.each(res, function(re) { cons.push(eval("re." + id)); }); this.containCheckChildExpand(cons,id); }, /* * 级选被包含子节点并展开全部 */ selectContainChilds:function(res,id){ var cons = new Array(); Ext.each(res, function(re) { cons.push(eval("re." + id)); }); this.containCheckChildAllExpand(cons,id); }
参数说明一下,cons是包含的数据数组,id是树节点中用于判断是否包含的属性,res是包含的json数组,比如包含数据是:["12","25"],id是text,那么判断是方法 就是node.text是否包含在这个数组中,如果是json数组,就先转换为一般数组,再判断。
使用的效果是只展开并且勾选了被包含的节点,不包含的节点将不会展开,当然代码中提供了全部展开且勾选被包含节点的方法,
完整代码如下:
/** * 树节点方法 */ Ext.applyIf(Ext.data.Model.prototype,{ /* * 重载 */ reload:function(){ var me=this; me.set('loaded', false); me.set('expanded',false); me.expand(); }, /* * 添加新节点时重载 */ loadNewNode:function(){ var me=this; me.set("leaf",false); me.reload(); }, /* * 级选(同步树) */ cascadeCheck:function(checked){ var me=this; me.childCheck(checked); me.parentCheck(checked); }, /* * 级选并展开子节点 */ cascadeCheckExpand:function(checked){ var me=this; me.childCheckExpand(checked); me.parentCheck(checked); }, /* * 级选子节点 */ childCheck:function(checked){ var me=this; me.cascadeBy(function(child) { child.set('checked', checked); }); }, /* * 级选父节点 */ parentCheck:function(checked){ var me=this; var parentNode = me.parentNode; if (parentNode != null) { if((checked&&!parentNode.get('checked'))||(!checked&&!parentNode.hasCheckedChild())){ parentNode.set('checked', checked); parentNode.parentCheck(checked); } } }, /* * 是否存在已选择子节点 */ hasCheckedChild:function(){ var node = this; var value=false; node.eachChild(function(child) { if (child.get('checked')) { value=true; return false; } }); return value; }, /* * 级选子节点并展开 */ childCheckExpand:function(checked){ var me=this; me.expand(false,function(childs){ if(childs!=null){ for(var i=0;i<childs.length;i++){ var child=childs[i]; child.set('checked', checked); child.childCheckExpand(checked); } } }); }, /* * 级选并展开被包含节点 */ containCheckChildExpand:function(cons,id){ var me=this; me.expand(false,function(childs){ if(childs!=null){ for(var i=0;i<childs.length;i++){ var child=childs[i]; if (cons.contain(child.get(id))) { child.set('checked', true); child.containCheckChildExpand(cons,id); }else if(child.get('checked')){ child.set('checked', false); child.childCheck(false); } } } }); }, /* * 级选被包含节点并展开全部 */ containCheckChildAllExpand:function(cons,id){ var me=this; me.expand(false,function(childs){ if(childs!=null){ for(var i=0;i<childs.length;i++){ var child=childs[i]; if (cons.contain(child.get(id))) { child.set('checked', true); }else if(child.get('checked')){ child.set('checked', false); child.childCheck(false); } child.containCheckChildAllExpand(cons,id); } } }); }, /* * 级选被包含节点(同步树) */ containCheckChild:function(cons,id){ var me=this; me.cascadeBy(function(child) { if (cons.contain(child.get(id))) { child.set('checked', true); }else{ child.set('checked', false); } }); }, /* * 级选被包含子节点 */ selectContainChildren:function(res,id){ var cons = new Array(); Ext.each(res, function(re) { cons.push(eval("re." + id)); }); this.containCheckChildExpand(cons,id); }, /* * 级选被包含子节点并展开全部 */ selectContainChilds:function(res,id){ var cons = new Array(); Ext.each(res, function(re) { cons.push(eval("re." + id)); }); this.containCheckChildAllExpand(cons,id); } });