iteye_614
2010-12-15 00:12 阅读 320

怎样判断ExtJS 异步tree的某个节点下的所有节点都已经加载了

最近在项目中遇到一个Ext 异步树头痛的问题:树中的每个节点都有一个checkbox,当勾选父节点时,也需要将其所有的子节点都选中,但是问题是当前还没有加载这些子节点。知道可以通过对父节点加tree.on(checkedchange,function(node){node.expand(..递归.)});的形式逐个展开所有的子节点,但是怎样才能知道父节点下的所有子节点都被展开选中了呢? 因为要在这之后对该父节点和其所有子节点做一些操作。

[code="java"]
tree.on('checkedchange',function(node,checked){
node.attributes.checked = checked;
node.expand(true,true,function(){
node.eachChild(function(child){
child.getUI.checked = checked;
child.attributes.checked = checked;
child.toggle();
child.fireEvent('checkedchange',child,checked,tree);
});
node.collapse();
});
},tree);
[/code]

这个操作可能是在用户选中了父节点的情况下马上就执行(从选中父节点到执行操作的时间很短,其所有子节点根本都还没有完全展开),这样就有可能会丢失一些还没有来得及展开完的子节点,所以需要一个判断所有节点都被异步加载完的事件......(父节点下所有子节点的节点个数先前是未知的)....

希望大家各抒己见,帮帮解决下,谢谢!!本人才30分的积分,给出5分吧。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

6条回答 默认 最新

  • 已采纳
    cyrilluce cyrilluce 2010-12-15 16:04

    ……
    我主要给你的是思路,程序什么的都是随手敲的,未经验证所以经常有些小错误,出错的地方是这里么?
    [code="js"]
    if(len<=0){
    taskDone(); // <--- 这里? 应该修改为 taskDone.call(this);
    return;
    }
    // 递归展开
    for(var i = 0, len = cs.length; i < len; i++) {
    cs[i].deepExpand(anim, taskDone, this);
    }

    [/code]

    逻辑是没问题,每展开一个子节点,都会调用taskDone回调。taskDone中有判断当前完成了多少个节点,如果根据计数判断都完成的就调用最终回调。

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2010-12-15 10:21

    扩展一下树节点,增加一个deepExpand接口
    [code="js"]
    Ext.override(Ext.tree.TreeNode, {
    deepExpand : function(anim, callback, scope){
    // 先展开本节点
    this.expand(true, anim, function(){
    // 然后展开子节点
    var cs = this.childNodes,
    expanded = 0,
    len = cs.length,
    taskDone = function(){
    // 每展开成功一个子节点,计数+1
    expanded++;
    // 如果所有子节点都展开,调用最终回调
    if(expanded >= len){
    this.runCallback(callback, scope || this, [this]);
    }
    };
    // 递归展开
    for(var i = 0, len = cs.length; i < len; i++) {
    cs[i].deepExpand(anim, taskDone, this);
    }
    }, this);
    }
    });
    [/code]

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2010-12-15 10:24

    哦。。。以上代码有个小错误,第4行调用expand首参数应该是false:
    [code="js"]
    this.expand(false, anim, function(){
    [/code]

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2010-12-15 11:19

    给你扩展的deepExpand不是有个回调参数吗?如果全部展开完毕就会调用这个回调

    换句话说,回调被调用时,该节点的所有子节点一定被全部展开完成

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2010-12-15 11:37

    你试试就知道了,这里是个[b]递归调用[/b],for循环中调用的是[b]自身[/b]:deepExpand

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2010-12-15 14:07

    可能是没考虑叶子节点的情况
    加上一句吧:
    [code="js"]
    if(len<=0){
    taskDone();
    return;
    }
    // 递归展开
    for(var i = 0, len = cs.length; i < len; i++) {
    cs[i].deepExpand(anim, taskDone, this);
    }
    [/code]

    点赞 评论 复制链接分享

相关推荐