學習過程是看DojoChina的陳治文老師講解的視頻
NameSpace
HTML文件中引入基本的三個Ext文件:
- < link type = "text/css" rel = "stylesheet" href = "ext/resources/css/ext-all.css" >
- < script type = "text/javascript" src = "ext/adapter/ext/ext-base.js" > </ script >
- < script type = "text/javascript" src = "ext/ext-all.js" > </ script >
這點和Dojo一樣,Dojo中也是需要引用一個統一的風格的樣式,不知道Ext中是不是也提供多樣的UI顯示主題,簡單看了一下resources/css目錄下面似乎沒有像Dojo一樣分層明確的themes,應該是採用其他的方式來實現的。
另外引入兩個Ext基本的JS,Ext基本功能的封裝。
把定義NameSpace的JS寫到一個單獨的js文件中
- /* 定義命名空間 */
- Ext.namespace("com.meizhi" );
- /**
- * 定義一個類
- * 寫法相當於com.meizhi.HelloWorld = new function() {};
- */
- com.meizhi.HelloWorld = Ext.emptyFn;
然後就可以在通過new來創建HelloWorld類的一個實例
- <script type= "text/javascript" >
- new com.meizhi.HelloWorld();
- </script>
OK,類的實例創建成功,當然,運行起來會沒有任何反應,因爲我們在類的定義中只給出了一個空的function。
看Ext是怎樣實現NameSpace的,看源代碼中的Ext.js
- namespace : function (){
- var a=arguments, o= null , i, j, d, rt;
- for (i=0; i<a.length; ++i) {
- d=a[i].split("." );
- rt = d[0];
- eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';' );
- for (j=1; j<d.length; ++j) {
- o[d[j]]=o[d[j]] || {};
- o=o[d[j]];
- }
- }
- },
- ...............
- Ext.ns = Ext.namespace;
- ...............
- Ext.ns("Ext" , "Ext.util" , "Ext.grid" , "Ext.dd" , "Ext.tree" , "Ext.data" ,
- "Ext.form" , "Ext.menu" , "Ext.state" , "Ext.lib" , "Ext.layout" , "Ext.app" , "Ext.ux" );
通過arguments得到namespace方法的參數,然後用點號分割成數組,再依次把空對象遞歸賦值進去,這樣Ext實現NameSpace的過程,而用點號進行連接,實際上就是對象的嵌套。
程序通過命名空間可以具有很好的組織形式,在java中命名空間的形式是通過package來實現的,Ext命名空間實際上是使用JavaScript的對象和對象屬性級聯來模擬的,和java的命名空間實現方式是不同的。將Ext的NameSpace用java的package來理解就容易多了。
命名空間別名
舉例:
- Mz = com.meizhi;
要求首字母必須大寫,其他字母小寫。
實際上就是通常命名空間是一個比較長的字符串,用一個縮寫來代替。
- Ext.namespace( "com.meizhi" );
- //命名空間別名
- Mz = com.meizhi;
- Mz.HelloWorld = Ext.emptyFn;
類別名
舉例
- HW = com.meizhi.HelloWorld
要求別名全部大寫,用來區別NameSpace的別名。
別名用的情況不是很多,在讀別人的代碼的時候能夠看明白是怎麼回事就好了。
類實例屬性
“類實例”感覺怪怪的,還是按照java中的概念來理解一下,java中類的一個實例,其實就是一個對象,java是面向對象的語言,Ext是用JavaScript實現的面向對象(這樣的說法不是很嚴謹,意會一下),那麼這裏的“類實例”其實就是我們通常所說的“對象”。
那麼“類實例屬性”,其實也就是對象的屬性。
來看一下類實例屬性的創建:
- Ext.namespace( "com.meizhi" );
- com.meizhi.Person = Ext.emptyFn;
- Ext.apply(com.meizhi.Person.prototype,{
- name:"<span style=" background-color: #ffff00; "><span style=" background-color: #ffffff;">meizhi</span>
- </span>
- ",
- sex:"男"
- });
prototype 是JavaScript中的函數原型,apply 方法是JavaScript中提供的對象綁定的方法(JavaScript中常用的對象綁定方法有兩種:apply和call),Ext.apply是對JavaScript提供的apply方法進行了一層封裝,方便使用,如果不瞭解的朋友可以先自己查一下相關的資料(參考:http://virgos.javaeye.com/blog/222199 ),這裏不做贅述。
來看一下調用:
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" >
- < html >
- < head >
- < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
- < title > NameSpace </ title >
- < link type = "text/css" rel = "stylesheet" href = "ext/resources/css/ext-all.css" >
- < script type = "text/javascript" src = "ext/adapter/ext/ext-base.js" > </ script >
- < script type = "text/javascript" src = "ext/ext-all.js" > </ script >
- < script type = "text/javascript" src = "js/helloworld.js" > </ script >
- < script type = "text/javascript" >
- var _person = new com.meizhi.Person();
- alert(_person.name);
- _person.name = "陳治文" ;
- alert(_person.name);
- </ script >
- </ head >
- < body >
- </ body >
- </ html >
結果:當進入頁面的時候,會彈出對話框,內容是“meizhi ”,點擊確定以後又彈出對話框,內容是“陳治文”。這是因爲在創建類Person的時候,創建了name屬性,並賦給它一個默認值“ meizhi ”, 在調用的時候我們更改了_person對象的name屬性,並賦值“陳治文”,這樣兩次alert的結果就不相同了。
這裏給對象屬性賦值操作體現了JavaScript的特性,在Java中我們如果在給對象屬性取值和賦值的時候,都是會用到getters和setters方法(每個POJO中都會有一大堆的屬性,然後用eclipse自動生成一大堆的getters和setters方法),而JavaScript的處理方式更加靈活,當然,這兩種方式各有利弊,需要在其中找到一個平衡點。
類實例方法
理解了Ext的類實例屬性,那麼類實例方法就好理解了,就是類裏面的一個方法。
- Ext.namespace( "com.meizhi" );
- com.meizhi.Person = Ext.emptyFn;
- Ext.apply(com.meizhi.Person.prototype,{
- name:"" ,
- sex:"" ,
- print:function (){
- alert(String.format("姓名:{0},性別:{1}" , this .name, this .sex));
- }
- });
"String.format"是Ext封裝的一個字符串處理方法,在Ext中有很多類似的工具方法(這一點Dojo中也是這樣做的,似乎框架中都會封裝一些常用的工具方法,方便使用)。
"String.format"方法中的參數格式,寫法很方便,不用做繁瑣的字段拼接。
上面代碼中Person類中定義了兩個類實例屬性name和sex,並且它們的默認值爲空,在構造Person對象實例的時候可以爲它們進行賦值操作。提供了一個類實例方法,將屬性輸出。
現在的代碼就有點兒像java中的類了,呵呵
來看調用:
- <script type= "text/javascript" >
- var person = new com.meizhi.Person();
- //設置屬性
- person.name = "<span style=" background-color: #ffff00; "><span style=" background-color: #ffffff;">meizhi</span>
- </span>
- ";
- person.sex = "男" ;
- //調用方法
- person.print();
- //爲該對象再次設置屬性
- person.name = "Katrana" ;
- person.sex = "女" ;
- person.print();
- </script>
可以看到彈出對話框中顯示:“姓名:meizhi ,性別:男”和“姓名:Katrana,性別:女”,是經過格式化以後的文本輸出樣式,也就是類實例方法中定義的樣式,從這裏也可以看到Ext封裝的"String.format"方法的使用效果。
類靜態方法
定義:在一個類級別上的共享方法。
來看定義
- Ext.namespace( "com.meizhi" );
- com.meizhi.Person = Ext.emptyFn;
- //這裏定義的 print方法 是 類實例方法
- Ext.apply(com.meizhi.Person.prototype,{
- name:"" ,
- sex:"" ,
- print:function (){
- alert(String.format("姓名:{0},性別:{1}" , this .name, this .sex));
- }
- });
- //這裏定義的 print方法 是 類靜態方法
- com.meizhi.Person.print = function (_name, _sex){
- var _person = new com.meizhi.Person();
- _person.name = _name;
- _person.sex = _sex;
- _person.print();
- }
對照Java代碼來看一下,理解的更快一些:
- Person.print(String name, String sex) {
- Person person = new Person();
- person.setName(name);
- person.setSex(sex);
- person.print();
- }
調用
- <script type= "text/javascript" >
- new com.meizhi.Person.print( "meizhi" , "男" );
- new com.meizhi.Person.print( "katrana" , "女" );
- </script>
調用的過程是 new com.meizhi.Person.print(name, sex),而不是先new com.meizhi.Person(),在調用它的print()方法。構造對象的過程是在靜態方法內部完成的,這裏需要好好的體會一下。
結果和上面的例子是一樣的。