`
microboat
  • 浏览: 59376 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

打造Ext2.0模块化单页系统(一)

阅读更多
    大多数web应用系统都会包含功能菜单和显示页面,功能菜单可以是页面左面的一棵树,也可以是一个可以切换的多标签页,而显示页面无非就是一个空白区域,点击相应的功能菜单,切换不同的内容。
    经常看到有人讨论如何用Ext加载iframe,这不失为一种简便的办法,但是它的弊端也是显而易见的。
    1.每个页面都需要引用庞大的Ext类库,这样的系统在局域网里还可以接受,但作为一个公网系统就让人无法忍受了。
    2.每个iframe中的页面自成一体,相互间的结合并不是那么紧密,数据互访也有一定难度。
    3.通常系统中都会有弹出窗口,并且在弹出窗口下面会有遮罩盖住整个页面来阻止用户进行非法操作,而iframe中的弹出窗口只能在本页范围内拖动,下面的遮罩也只能盖住本页。

    既然选择了Ext2.0这个庞大的框架,为什么我们不更Ajax一点呢,下面就谈谈如何运用Ext2.0框架来打造一个真正的模块化的单页系统。

    一个单页系统应该有以下特点:
    1.一个模块基类来封装所有模块的公共属性和方法。
    2.封装每个模块成单独的js文件,并按需加载。
    3.整个程序有一个主程序类来管理所有的模块的加载与销毁。

   先来看看模块基类的代码:
//定义程序的命名空间
Ext.namespace('demo');
demo.module = function(main){
    this.main = main;
    this.init();
}

Ext.extend(demo.module, Ext.util.Observable, {
    init : Ext.emptyFn
});

首先定义一个程序的命名空间(这是个好习惯,省得在代码海洋中找不到哪些是自己定义的类,哪些是系统本身的类。)
模块既然是被主窗口加载进来的,那么相对这个模块来说它必然有个父窗口来显示它,我们把这个父窗口作为参数传给模块,让它知道在哪里显示自己。这样对每个继承它的子类来说,this.main就是它的父窗口。
模块基类还包含一个init方法,这个方法将被模块子类重载,模块子类的界面渲染就交给这个方法了。
当然你还可以在这个基类中添加每个模块必需的公共属性和方法,让我们的模块实现高度统一。

模块基类写好了,接下来写主程序类。用面向对象的方法写js刚开始会有点不习惯,我们早已习惯了function嘛,但是如果你能坚持改变你的代码写法,你会渐渐的发现这种写法的优越性,尤其在js动辄几百行的ajax时代。

在面向对象的世界中,尘归尘、土归土,一切皆对象。

在这个demo中,整个程序分为3个模块,用TabPanel来导航。

主程序类:
demo.app = function(){    
    this.init();
}
Ext.extend(demo.app, Ext.util.Observable, {
    init: function(){       
        this.tab1 =  new Ext.Panel({
            title: '模块一',
            id: 'module1',
            layout: 'fit'
        });
        
        this.tab2 =  new Ext.Panel({
            title: '模块二',
            id: 'module2',
            layout: 'fit'
        });

        this.tab3 =  new Ext.Panel({
            title: '模块三',
            id: 'module3',
            layout: 'fit'
        });

        this.body = new Ext.TabPanel({
            region:'center',
            margins:'0 5 0 5',
            autoScroll: true,
            items: [this.tab1, this.tab2, this.tab3]
        });

        var viewport = new Ext.Viewport({
            layout:'border',
            items:[
                new Ext.BoxComponent({region:'north', el:'header', height:60}),
                new Ext.BoxComponent({region:'south', el:'footer', height:50}),
                this.body
            ]
        });

        this.body.on('tabchange', this.tabActive, this);
        this.loadMask = new Ext.LoadMask(this.body.body);
        this.body.activate(this.tab1);
    },
    tabActive: function(p,t){
        if(this[t.id]){
            return false;
        }
        this.loadMask.show();
        Ext.Ajax.request({
            method:'GET',
            url: 'modules/'+t.id+'.js',
            scope: this,
            success: function(response){
                var module = eval(response.responseText);
                this[t.id] = new module(t);
                this.loadMask.hide();
            }
        });
    }
});

Ext.onReady(function(){
    Ext.QuickTips.init();
    myApp = new demo.app();
});


首先定义了一个初始化方法来渲染页面,这个页面采用Ext.Viewport的'border'布局,分为头部、中部和脚部3个区域,头部和脚步是html上的2个div,用来放程序的logo和版权信息什么的。中间的区域是个TabPanel,其中每个Tab对于一个模块的显示窗口,也就是模块的this.main。
动态加载模块的行为就由TabPanel的tabchange来触发,考虑到加载模块需要一定时间,我们还需要在TabPanel的body中定义一个Ext.LoadMask来让用户知道程序在读取数据。在模块加载之前让它show出来,加载结束后hide。
需要注意的是这个TabPanel在配置参数中并没有设置activeTab,而是在定义完Ext.LoadMask后才让它手动激活第一个Tab。

好了,接下来该定义tabActive方法了,这个方法接受2个参数:p是TabPanel,t是当前被激活的Tab(请参阅API)。

思考一个问题,我们如何让主程序知道某个模块已经加载,而防止重复加载模块的JS文件呢?这里提供了一个简便的办法:
我们利用每个Tab的id作为模块被实例化后的对象名,这样就可以根据当前被激活Tab的id来反射出相应的模块对象是否已经被创建了。
另外为了简便,我们把每个模块的js文件也命名为相应Tab的id,这样就可以根据当前被激活Tab的id来加载相应的JS文件。

来看tabActive方法,先不去管开始的if语句,看下面的Ext.Ajax.request。很明显,这行语句根据当前被激活Tab的id异步加载了一个相应的JS模块文件,response.responseText表示返回的数据字符。感谢JS强大的eval方法,这个方法可以把一段字符串当作代码来执行(就像SQL里面的EXEC语句)。执行完这行后我们得到了什么?对了,就是模块子类。
接下来把模块子类实例化,把当前激活的Tab作为它的main传入,把这个模块对象用Tab的id来命名。
this[t.id] = new module(t);这里的this指向主程序类,也就是说模块作为主程序的一个属性。
最后把Ext.LoadMask隐藏吧,模块对象以及被创建好了。
回头来看if语句,当一个模块被实例化后,主程序相应的模块属性就被创建,这里就可以判断一下相应的模块有没有被实例化过,已经存在就返回,不执行下面的Ajax请求了。

最后把主程序类实例化,大功告成。

题外话:有人说用panel的autoload也能实现上面的功能。没错,但是这样做失去了一些灵活性,其实autoload的实现方法和上面的差不多。

下次我们再来看看每个模块是怎么写的。
未完待续。。。
分享到:
评论
11 楼 别大号 2010-03-19  
楼主,这样时间也太长了吧:
点击菜单请求打开一个页面
-->ajax请求该页面的js代码字符串
-->网络响应
-->浏览器解释(eval)返回的字符串
-->浏览器渲染页面元素

这么长的执行过程,要在每次打开一个页面都走一次,这是难以接受的!

只属个人意见,不知道我有没有理解错误
10 楼 七月十五 2010-02-23  
非常不错的思路,刚开始着手ExtJS。我崇尚单一入口。“在面向对象的世界中,尘归尘、土归土,一切皆对象。 ”很有道理。
9 楼 tomsxh001 2009-06-10  
想在第41行加入以下代码:
this.body.on('beforeremove',this.tabClose,this);

59行后加入以下代码:
tabClose: function(p,t){
		this[t.id]=null;
	}

如果tab可关闭的话,防tab关闭后打不开.
8 楼 peak 2008-07-28  
越看越象官方提供的例子,不过官方的确实是onload
7 楼 flare 2008-07-26  
题外话:有人说用panel的autoload也能实现上面的功能。没错,但是这样做失去了一些灵活性,其实autoload的实现方法和上面的差不多。

你的实现感觉上并不比panel的autoload更好,而且你的实现必须建立在新的标签页是由js动态生成的,如果新的标签页是html与jsp的话,你的实现也起不到作用。

不过你的模块化思想与用面向对象的方式写js代码值得推广。
6 楼 microboat 2008-04-16  
fangzhouxing:
不明白你的意思,按需加载就是为了解决网速慢的问题嘛。
5 楼 fangzhouxing 2008-04-16  
作者所谓的单页系统就是One Page One Application吧。文章提供了很好的思路。

根据我的经历,按需加载可以用在开发阶段,应用正式运行阶段应该把所有js合并压缩成一个文件加载,可以显著提高性能。

4 楼 microboat 2008-04-16  
hzyang0709:
在Ext的类定义中,每个类具有配置参数(Config Options)、属性(Public Properties)、方法(Public Methods)和事件(Public Events)。配置参数和属性不难理解,方法可以理解为这个类可以做的行为,而事件可以理解为当满足一定条件时被自动触发的行为。
Ext.TabPanel有个事件"tabchange",表示当tab被切换时自动触发,它接受2个参数tabchange : ( TabPanel this, Panel tab ) ,API中有详细说明。
在我的代码里this.body.on('tabchange', this.tabActive, this);表示当tab被切换时自动触发this.tabActive这个方法,执行边界是this(主程序类)。
3 楼 hzyang0709 2008-04-15  
好文章 感谢指点,最近正在写这个东西 确实感到很费劲 在网上看到一个人的例子 (ext的指导中写了big app的那个,很有帮助) 不过好像大家都用的是tabpanel 如果要是只用panel 怎么改边里面内容呢? 或者说我有个layout,只想改center位置的panel下的items怎改呢?比如开始是个tree 之后是个grid 这个怎么处理呢?
还有个问题是 您代码里有一行
tabActive: function(p,t)
   想知道这个参数是啥?您是怎么知道这个参数的呢?
经常看到各种函数调用 但是这些参数怎么传?从哪得到的?是什么意思?一直没有头绪
望指点一下
2 楼 HexUzHoNG 2008-04-15  
期待楼主的下一篇文章。

最近刚学extjs,感觉有点不习惯。公司原来都是用自己的一套JS框架。写东西基本上不用写JS,有点类似jindw的JSI装饰器组件,但更简单。

用extjs,页面感觉都是自己在用js生成的,不熟悉内部运行机制,总感觉不稳妥。还是喜欢那种代码全部在自己掌握之中的感觉。呵呵
1 楼 sp42 2008-04-15  
说得很好。的确如何在单页面内管理总多个模块是逼在眉睫的问题,楼主提供了一个很好的思路。

相关推荐

    ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记

    ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记ext2.0笔记...

    最新的ext2.0下载

    EXT是Web应用程序开发中的一款强大的JavaScript库,它专注于创建数据驱动的用户...在实际开发中,结合EXT2.0提供的API参考和示例,开发者能够实现各种复杂的业务逻辑,提升用户体验,打造出功能强大且美观的Web应用。

    ext-2.0 ext-2.0 ext-2.0 ext-2.0 ext-2.0

    ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0ext-2.0

    ext2.0官方文档

    7. **软链接和硬链接**:EXT2.0支持软链接(符号链接)和硬链接,前者是一个指向另一个文件的指针,后者则在文件系统中创建多个指向相同inode的入口。 8. **磁盘配额**:EXT2.0也支持磁盘配额,可以限制特定用户或...

    ext2.0(jsp标签)

    EXT 2.0是Sencha公司推出的一个基于JavaScript的开源用户界面库,专门用于构建富互联网应用程序(RIA)。它提供了一套完整的组件化、可定制的UI控件,包括树形视图、菜单、弹出式菜单等,使得开发者能够轻松创建具有...

    Ext2.0 中文文档

    EXT,全称Ext JS,是一种基于JavaScript...总之,EXT2.0作为一款强大的前端开发框架,为构建现代Web应用提供了丰富的工具和方法。通过深入学习和实践,开发者可以利用EXT2.0构建出高效、美观、功能强大的Web应用程序。

    Ext2.0中文文档

    Ext 2.0是Sencha公司开发的一个JavaScript库,主要用于构建富互联网应用程序(RIA)。这个中文文档包含了关于Ext 2.0的详细说明,对于开发者来说是一个非常宝贵的资源,可以帮助他们理解和使用这个强大的前端框架。 ...

    ext2.0官方文档(chm),Ext 2.0 简明教程,Ext2经典应用

    5. **ext2.0官方文档 .rar**:这是官方文档的另一个备份,与第一个CHM文件相同,提供另一种访问方式。 6. **ext PPT.rar**: 这可能是关于Ext 2.0的一组PowerPoint演示文稿,可能包含了一些讲座、研讨会或培训课程的...

    EXT2.0在本地浏览API的插件

    EXT2.0是一款基于JavaScript的富客户端开发框架,它提供了丰富的组件库和强大的数据管理功能,使得在浏览器端构建复杂的用户界面变得简单。本插件是EXT2.0针对本地浏览API的扩展,旨在增强EXT应用程序对本地资源的...

    Ext2.0组件,全组件和帮助手册

    Ext2.0是Ext JS库的一个早期版本,它是一个用于构建富互联网应用程序(RIA)的JavaScript框架。这个框架提供了一套完整的UI组件和强大的数据管理功能,使得开发者能够创建交互性强、功能丰富的Web应用。全组件和帮助...

    EXT2.0最新压缩包

    EXT2.0是一种广泛应用于Linux操作系统中的文件系统,它的全称是Extended File System Version 2.0。在Linux世界中,文件系统是管理和组织磁盘数据的核心组件,它决定了文件如何存储、检索以及如何实现高效的读写操作...

    EXT2.0 GRID 示例

    EXT2.0是EXT库的一个早期版本,它提供了丰富的用户界面组件,包括GRID,用于展示大量结构化数据。 EXT2.0 GRID组件是EXT库中的核心部分,它允许开发者以表格形式显示数据,并提供了一系列功能,如排序、分页、筛选...

    ext2.0API

    随着技术的发展,EXT2也经历了多次升级,其中EXT2.0 API是一个重要的里程碑,它引入了一系列新特性以提升系统的性能和稳定性。 EXT2.0 API的改进主要集中在以下几个方面: 1. **日志记录**:EXT2.0引入了日志记录...

    ext 2.0

    Ext 2.0是一个强大的JavaScript库,专门用于构建富客户端应用程序。它是一个基于Ajax技术的开发框架,Ajax(Asynchronous JavaScript and XML)的核心理念是通过后台与服务器进行异步数据交换,无需刷新整个页面,...

    ext2.0项目源代码供大家学习ext使用

    9. **Ext Designer支持**:EXT 2.0可能还支持EXT Designer,一个可视化的布局编辑工具,使得非程序员也能创建EXT界面。 10. **主题和皮肤**:EXT提供了多种预设的主题,可以改变整个应用程序的外观和感觉。 11. **...

    EXT2.0中文教程

    EXT2.0中文教程是一个专为Windows用户设计的教育资源,旨在帮助用户理解和操作EXT2.0文件系统。EXT2.0是Linux操作系统中早期广泛使用的日志式文件系统,它在1993年由Rene Rebe开发,作为EXT1的升级版。EXT2.0在性能...

    EXT 2.0 酒店管理系统

    EXT是一种基于Web的JavaScript框架,以其高性能、可扩展性和丰富的用户界面组件而闻名,EXT 2.0 酒店管理系统充分利用了这些优势,打造了一个直观易用且功能强大的系统。 首先,我们来了解一下EXT的核心特性。EXT...

    EXT 2.0 一个完整例子

    ext2.0 的一个小例子。基本上把ext 的功能都用到了 一个不错的东西

    ext2.0中文文档

    总结,EXT2.0中文文档详细阐述了这一经典文件系统的内在机制和管理方法,为Linux用户提供了深入理解文件系统运作的基础,对学习Linux系统管理和优化具有重要意义。通过阅读这份文档,读者不仅可以掌握EXT2.0的核心...

    EXT2.0 简明教程.rar

    通过这个教程,学习者可以掌握如何在Linux系统中创建、挂载、格式化EXT2.0文件系统,以及如何进行基本的文件系统维护,如使用`df`和`du`命令检查磁盘空间,使用`fsck`工具检查和修复文件系统错误,理解inode的概念和...

Global site tag (gtag.js) - Google Analytics