首先是面向对象的思想建立,EXTJS虽然是基于Javascript的,但是在对象上,写法确实跟Javascript不太一样.EXTJS让Javascript的面向对象更接近强类型后台语言的写法,现在写EXTJS的有很多人没有按照正确的EXTJS式的面向对象的思想去写,例如一个简单的对象:
Ext.ns(“Ext.ux.Panel”); Ext.ux.Panel=function(){ return new Ext.Panel(); }
这样写是没有错误的,EXTJS底层很多也是这样写的例如基类Observable
EXTUTIL.Observable.prototype = function(){ var filterOptRe = /^(?:scope|delay|buffer|single)$/, toLower = function(s){ return s.toLowerCase(); }; return { //省略若干代码 }
这就是Javascript最常用的写法,但是在开发过程中我们能这样去写EXTJS对象吗?
在大多数情况下这显然是不可行的,当整个项目采用Extjs编写之后,这样的代码会让接手的人有一种无从下手的感觉(这个人可能就是两三个月后的你自己).
我们应该怎么样去写一个对象让代码看起来更简洁清晰呢?还是查看EXTJS的源码,UI组件Window最能说明问题:
Ext.Window = Ext.extend(Ext.Panel, { //省略若干属性 baseCls : 'x-window', //.......省略若干属性 initComponent : function(){ Ext.Window.superclass.initComponent.call(this); //省略若干函数体 } //.......省略若干函数
Window是继承自Panel的,并为Panel添加了拖拽等功能,到这里,一切就真相大白了,Panel继承自BoxComponent,理论上来讲,我们自己的组件完全可以基于Panel来做,我们可以暂且将Panel作为我们所有组件的容器,我们所写的各种组件都可以被包在这个Panel里面去.
我们首先构建出自定义组件(这里以登陆为例)的轮廓:
Ext.namespace("Lesson1.FirstPanel"); /** * @author andy_ghg * @version 2009年9月24日23:22:09 * @description 第一个派生类 * @class Lesson1.FirstPanel * @extends Ext.Panel */ Lesson1.FirstPanel=Ext.extend(Ext.Panel,{ frame:true, //初始化函数 initComponent:function(){ //继承父类的initComponent函数 Lesson1.FirstPanel.superclass.initComponent.call(this,arguments); } }); //*测试 Ext.onReady(function(){ var panel=new Lesson1.FirstPanel({ title:"标题", height:300, width:400, renderTo:Ext.getBody() }); }); //*/
运行之后就是一个很普通的Panel,不要着急,我们还要往里面添加东西,登陆需要一个表单,我们继续写下去为这个组件添加一个表单:
Lesson1.FirstPanel=Ext.extend(Ext.Panel,{ frame:true, //初始化函数 initComponent:function(){ //继承父类的initComponent函数 Lesson1.FirstPanel.superclass.initComponent.call(this,arguments); //为该组件添加了一个FormPanel this.formPanel=new Ext.FormPanel({ defaults:{anchor:"95%",allowBlank:false}, labelWidth:55, defaultType:"textfield", items:[{ fieldLabel:"用户名", name:"username" },{ fieldLabel:"密码", inputType:"password", name:"password" }] }); //将表单列入到panel的items里去 this.add(this.formPanel); } });
然后我们可以将这个Panel包含在一个Window里面去,让他更像一个登陆窗口:
//*测试 Ext.onReady(function(){ var panel=new Lesson1.FirstPanel({ height:100, width:300, layout:"fit" }); new Ext.Window({ title:"登陆", items:[panel], buttons:[{ text:"确定" },{ text:"取消" }] }).show(); }); //*/
OK,到此为止,我们已经将这个登陆组件的大框架已经搭建好了,我们现在开始为我们的登录组件添加一个公开的函数让外部去调用:
Ext.namespace("Lesson1.FirstPanel"); /** * @author andy_ghg * @version 2009年9月24日23:22:09 * @description 第一个派生类 * @class Lesson1.FirstPanel * @extends Ext.Panel */ Lesson1.FirstPanel=Ext.extend(Ext.Panel,{ frame:true, //初始化函数 initComponent:function(){ //继承父类的initComponent函数 Lesson1.FirstPanel.superclass.initComponent.call(this,arguments); //为该组件添加了一个FormPanel this.formPanel=new Ext.FormPanel({ defaults:{anchor:"95%",allowBlank:false}, labelWidth:55, defaultType:"textfield", items:[{ fieldLabel:"用户名", name:"username" },{ fieldLabel:"密码", inputType:"password", name:"password" }] }); this.add(this.formPanel); }, // 提交表单的函数 submitForm:function(){ alert(this.formPanel); // this.formPanel.getForm().submit({ // url:"", // success:function(){}, // failure:function(){} // }) } }); //*测试 Ext.onReady(function(){ var panel=new Lesson1.FirstPanel({ height:100, width:300, layout:"fit" }); new Ext.Window({ title:"登陆", items:[panel], buttons:[{ text:"确定", handler:function(){ panel.submitForm(); } },{ text:"取消" }] }).show(); }); //*/
至此,我不会再继续写下去了,我也不会提供源码,你可以充分发挥你的想象力去改造它,去感受一下这种写法的好处与优点,以及他即将会引发什么样的困惑.思考之后你才能有更深刻的了解.(你可以直接继承Window而不是继承Panel来做这个登录组件)