weixin_42387562
2010-07-23 00:59 阅读 377

extJS 如何在Panel加载组件时显示遮罩层?

效果就是一个panel,是空白的,然后这个panel写一个loadPanel的方法,调用这个方法可以动态为panel加载组件,期间需要显示遮罩来提示'加载中,请稍候...',如果加载成功则除去遮罩层,并返回加载的组件,如果不成功则遮罩提示'加载失败'并返回null
我的代码如下,但只是美好的幻觉代码而已:
[code="java"]
myPanel=Ext.extend(Ext.Panel,{
loadPanel : function(config){
this.el.mask('加载中,请稍候...');
//创建组件
var c = null;
try{
c = Ext.create(config);
this.add(c);
this.doLayout();
this.el.unmask();
}
catch(err){
this.el.mask('加载失败!');
}
finally{
return c;
}
}
});
[/code]
上面的代码看起来好像挺有条理的,但有很多破绽:
1.'加载中'的提示如果不强行中断(比如在创建组件前alert中断进程),那么永远都看不见这个提示,就已经执行到create了,但是由于javascript是单线程的,所以在create的时候是假死状态,根本不可能显示出'加载中'的提示,我怀疑mask是延时执行的!
2.由于是单线程,所以除非try抛出异常,否则肉眼根本看不见遮罩层的显示,因为单线程导致浏览器假死.
3.如果使用defer延迟create的执行,那么这个方法又无法返回结果,因为javascript没有sleep等待功能,defer只是推迟几秒再执行指定的方法,只是一个回调,并不能强制线程等待,所以用defer则永远得不到create出来的c

希望大家帮忙如何实现组件加载的遮罩效果

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

2条回答 默认 最新

  • 已采纳
    cyrilluce cyrilluce 2010-07-23 10:06

    create中[b]同步[/b]访问后台?

    应避免使用同步请求,这段时间浏览器完全阻塞住,又什么事都不干,太浪费了。你可以看到Ext的API根本就不提供同步Ajax请求。

    那还是之前说的,应该换回调的方式编码

    JS单线程其实很好的,要知道多线程编程的复杂度…… 回调用好了,浏览器基本不会干无用功。
    不过需要把任务分配好,不能有时间过长的任务一次运行,而应该用defer等拆成异步运行,浏览器始终能即时响应。

    示例:
    [code="js"]
    loadPanel : function(opt, callback, scope){
    opt.callback = function(options, success, response){
    // 解析,创建,添加,布局
    callback.call(scope, success, cmp);
    this.el.unmask();
    };
    opt.scope = this;
    this.el.mask();
    Ext.Ajax.request(opt);
    }
    [/code]

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2010-07-23 09:03

    这里运行占用时间最长的应该是this.doLayout,而不是create,所以可以将doLayout及unmask延后执行,这样mask能更新出来。

    [code="js"]
    myPanel=Ext.extend(Ext.Panel,{
    loadPanel : function(config){
    this.el.mask('加载中,请稍候...');
    //创建组件
    var c = null;
    try{
    c = Ext.create(config);
    (function(){
    this.add(c);
    this.doLayout();
    this.el.unmask();
    }).defer(1, this);
    // this.add(c);
    // this.doLayout();
    // this.el.unmask();
    }
    catch(err){
    this.el.mask('加载失败!');
    }
    finally{
    return c;
    }
    }
    });
    [/code]

    或者,不用return传递,改用callback,这样能避免很多问题。比如loadPanel后续逻辑要求组件已经render完毕

    其实个人认为mask操作拖慢了界面响应,异步请求时用用还不错,都是本地执行时还不如省下时间让任务快点执行完。

    点赞 评论 复制链接分享

相关推荐