<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 78,  comments - 48,  trackbacks - 0
    下載本文源代碼

      一、 引言

      在第一部分中,我們討論了AJAX基礎(chǔ)——建立從腳本到服務(wù)器的通訊的能力,這正是使HTML頁(yè)面具有動(dòng)態(tài)能力的原因所在。然而,這就意味著我們已準(zhǔn)備好拋棄我們自己版本的Yahoo郵件嗎?不,還沒(méi)有。原因在于:AJAX是一個(gè)混合的祝福。一方面,它使我們能夠在Web上創(chuàng)建豐富的桌面級(jí)的應(yīng)用程序;另一方面,如果我們把"翻頁(yè)面式"的Web應(yīng)用程序與客戶端/服務(wù)器或Swing版本的程序進(jìn)行比較,那么會(huì)看到其開(kāi)發(fā)實(shí)踐并不很相同。我們將需要習(xí)慣于這樣的事實(shí):構(gòu)建一個(gè)豐富的UI需要時(shí)間。須知,允許用戶實(shí)現(xiàn)更大的靈活性也就相應(yīng)地需要付出更多的時(shí)間為代價(jià)。

      最后的答案當(dāng)然要依賴于大量的組件庫(kù)、框架以及具有工業(yè)力量的開(kāi)發(fā)工具。且不考慮工具,本文集中于討論在今天對(duì)于AJAX熱心者有哪些技術(shù)是可用的。在強(qiáng)調(diào)需要構(gòu)建可重用的商業(yè)組件的同時(shí),本文將重點(diǎn)分析"隱含的"JavaScript中的面向?qū)ο蟮牧α俊A硗猓趶?qiáng)調(diào)需要構(gòu)建定制的UI組件的同時(shí),本文將介紹一個(gè)簡(jiǎn)便的方法——用定制的客戶端HTML標(biāo)簽來(lái)封裝描述邏輯。

      二、 AJAX語(yǔ)言——對(duì)象面向的JavaScript

      由定義來(lái)看,JavaScript是典型的AJAX語(yǔ)言。不同于Java,JavaScript并不強(qiáng)調(diào)OO風(fēng)格的編碼。然而,令人吃驚的是JavaScript居然全面支持所有的OO語(yǔ)言的主要屬性:封裝、繼承和多態(tài)性。Douglas Crockford甚至稱(chēng)JavaScript是"世界上最易被誤解的編程語(yǔ)言"。讓我們回顧一下JavaScript的面向?qū)ο蟮牡胤桨伞?BR>
      數(shù)據(jù)類(lèi)型

      在Java中,一個(gè)類(lèi)定義了一個(gè)數(shù)據(jù)和它的相關(guān)行為的組合。盡管JavaScript保留了class關(guān)鍵字,但是它不支持與常規(guī)OOP語(yǔ)言一樣的語(yǔ)義。

      這聽(tīng)起來(lái)可能覺(jué)得奇怪,但是在JavaScript中,對(duì)象是用函數(shù)來(lái)定義的。事實(shí)上,通過(guò)在下面的示例中定義一個(gè)函數(shù),你就定義了一個(gè)簡(jiǎn)單的空類(lèi)Calculator:

    function Calculator() {}

      一個(gè)新的實(shí)例的創(chuàng)建與在Java中相同-使用new操作符:

    var myCalculator = new Calculator();

      上面這個(gè)函數(shù)不僅定義一個(gè)類(lèi),而且還擔(dān)當(dāng)了一個(gè)構(gòu)造器。在此,操作符new實(shí)現(xiàn)了這一魔術(shù)-實(shí)例化一個(gè)類(lèi)Calculator的對(duì)象并且返回一個(gè)對(duì)象參考而不是只調(diào)用該函數(shù)。

      創(chuàng)建這樣的空類(lèi)是沒(méi)錯(cuò),但在實(shí)際中并沒(méi)有多大用處。下面,我們準(zhǔn)備使用一個(gè)Java-腳本原型結(jié)構(gòu)來(lái)填充類(lèi)定義。JavaScript使用原型當(dāng)作創(chuàng)建對(duì)象的模板。所有的原型屬性和方法被參考引用地復(fù)制到一個(gè)類(lèi)的每個(gè)對(duì)象中,所以它們都具有相同的值。你可以改變一個(gè)對(duì)象中的原型屬性的值,并且該新值會(huì)覆蓋從原型中復(fù)制過(guò)來(lái)的缺省值,但是這僅對(duì)于在一個(gè)實(shí)例中。下列語(yǔ)句將把一個(gè)新屬性添加到Calculator對(duì)象的原型上:

    Calculator.prototype._prop = 0;

      既然JavaScript并沒(méi)有提供一個(gè)方法來(lái)從句法上表示一個(gè)類(lèi)定義,那么我們將使用with語(yǔ)句來(lái)標(biāo)記該類(lèi)的定義邊界。這也將使得示例代碼更為短小,因?yàn)樵搘ith語(yǔ)句被允許在一個(gè)指定的對(duì)象上執(zhí)行一系列的語(yǔ)句而不需要限制屬性。

    function Calculator() {};
    with (Calculator) {
     prototype._prop = 0;
     prototype.setProp = function(p) {_prop = p};
     prototype.getProp = function() {return _prop};
    }

      到目前為止,我們定義了并且初始化了公共變量_prop,并且為它提供了getter和setter方法。

      需要定義一個(gè)靜態(tài)變量?你可以把靜態(tài)變量當(dāng)作是為類(lèi)所擁有的一個(gè)變量。因?yàn)樵贘avaScript中的類(lèi)用函數(shù)對(duì)象來(lái)描述,所以我們只需要把一個(gè)新屬性添加到該函數(shù)上:

    Calculator.iCount=0;

      現(xiàn)在,既然這個(gè)iCount變量是一個(gè)Calculator對(duì)象的屬性,那么它將會(huì)被類(lèi)Calculator的所有實(shí)例所共享。

    function Calculator() {Calculator.iCount++;};

      上面的代碼計(jì)算類(lèi)Calculator的所有實(shí)例的個(gè)數(shù)。

      封裝

      通過(guò)使用如上面所定義的"Calculator",我們可以存取所有的"class"數(shù)據(jù);然而,這增加了派生類(lèi)中命名沖突的危險(xiǎn)性。我們明顯地需要封裝以把對(duì)象看作自包含的實(shí)體。

      數(shù)據(jù)封裝的一種標(biāo)準(zhǔn)語(yǔ)言機(jī)制是使用私有變量。并且一個(gè)常用的仿效一個(gè)私有變量的JavaScript技術(shù)是在構(gòu)造器中定義一個(gè)局部變量;這樣以來(lái),該局部變量的存取只能經(jīng)由getter和setter來(lái)實(shí)現(xiàn)-它們是該構(gòu)造器中的內(nèi)部函數(shù)。在下列實(shí)例中,_prop變量在Calculator函數(shù)中定義并且在函數(shù)范圍外不可見(jiàn)。其中有兩個(gè)匿名的內(nèi)部函數(shù)(分別被賦予setProp和getProp屬性)讓我們存取"私有"變量。另外,請(qǐng)注意,這里this的使用-十分相似于在Java中的用法:

    function Calculator() {
     var _prop = 0;
     this.setProp = function (p){_prop = p};
     this.getProp = function() {return _prop};
    };

      常常被忽視的是在JavaScript中作如此封裝所付出的代價(jià)。須知,這種代價(jià)可能是巨大的,因?yàn)閮?nèi)部函數(shù)對(duì)象對(duì)于該"class"的每一個(gè)實(shí)例被不斷地重復(fù)創(chuàng)建。

      因此,既然基于原型構(gòu)建對(duì)象速度更快并且消費(fèi)更少些的內(nèi)存,那么我們?cè)谧顝?qiáng)調(diào)性能的場(chǎng)所特別支持使用公共的變量。請(qǐng)注意,你可以使用命名慣例來(lái)避免名稱(chēng)沖突-例如,在公共的變量的前面加上該類(lèi)名。
    繼承

      乍看之下,JavaScript缺乏對(duì)類(lèi)層次的支持,這很相似于面向?qū)ο笳Z(yǔ)言的程序員對(duì)于現(xiàn)代語(yǔ)言的期盼。然而,盡管JavaScript句法沒(méi)有象Java一樣支持類(lèi)繼承,但是我們?nèi)匀荒軌蛟贘avaScript中實(shí)現(xiàn)繼承-通過(guò)把已定義類(lèi)的一個(gè)實(shí)例拷貝到其派生類(lèi)的原型當(dāng)中。

      在我們提供舉例之前,我們需要介紹一個(gè)constructor屬性。JavaScript保證每一個(gè)原型中包含constructor-它擁有到該構(gòu)造器函數(shù)的一個(gè)參考。換句話說(shuō),Calculator.prototype.constructor包含一個(gè)到Calculator()的參考。

      現(xiàn)在,下面的代碼顯示了怎樣從基類(lèi)Calculator派生類(lèi)ArithmeticCalculator。其中,"第一行"取得類(lèi)Calculator的所有的屬性,而"第二行"把原型constructor的值恢復(fù)成ArithmeticCalculator:

    function ArithmeticCalculator() { };
    with (ArithmeticCalculator) {
     ArithmeticCalculator .prototype = new Calculator();//第一行
     prototype.constructor = ArithmeticCalculator;//第二行
    }

      就算上面的實(shí)例看起來(lái)象一個(gè)合成體而不象是繼承,但是JavaScript引擎還是清楚這個(gè)原型鏈的。特別是,instanceof操作符會(huì)正確地適用于基類(lèi)和派生類(lèi)。假定你創(chuàng)建類(lèi)ArithmeticCalculator的一個(gè)新實(shí)例:

    var c = new ArithmeticCalculator;

      表達(dá)式c instanceof Calculator和c instanceof ArithmeticCalculator都會(huì)成立。

      注意,在上面示例中的基類(lèi)的constructor是在初始化ArithmeticCalculator原型時(shí)被調(diào)用的,而在創(chuàng)建派生類(lèi)的實(shí)例時(shí)是不被調(diào)用的。這可能會(huì)帶來(lái)不想要的負(fù)面影響,而且為了實(shí)現(xiàn)初始化你應(yīng)該考慮創(chuàng)建一個(gè)獨(dú)立的函數(shù)。由于該構(gòu)造器并不是一個(gè)成員函數(shù),所以它無(wú)法通過(guò)this參考引用調(diào)用。我們將需要一個(gè)能調(diào)用超類(lèi)的"Calculator"成員函數(shù):

    function Calculator(ops) { ...};
    with (Calculator) { prototype.Calculator=Calculator;}

      現(xiàn)在,我們可以寫(xiě)一個(gè)繼承類(lèi)-它顯式地調(diào)用基類(lèi)的構(gòu)造器:

    function ArithmeticCalculator(ops) { this.Calculator(ops);};
    with (ArithmeticCalculator) {
     ArithmeticCalculator .prototype = new Calculator;
     prototype.constructor = ArithmeticCalculator;
     prototype.ArithmeticCalculator = ArithmeticCalculator;
    }

      多態(tài)性

      JavaScript是一種非類(lèi)型化的語(yǔ)言-在此,一切都是對(duì)象。因此,如果有兩個(gè)類(lèi)A和B,它們都定義一個(gè)foo(),那么JavaScript將允許在A和B的實(shí)例上多態(tài)地調(diào)用foo()-即使不存在層次關(guān)系(雖然是可實(shí)現(xiàn)的)。從這一角度來(lái)看,JavaScript提供一個(gè)比Java更寬的多態(tài)性。這種靈活性,象往常一樣,也要付出代價(jià)。在這種情況中,代價(jià)是把類(lèi)型檢查工作代理到應(yīng)用程序代碼。具體地說(shuō),如果需要檢查一個(gè)參考確實(shí)指向一個(gè)所希望的基類(lèi),那么這可以通過(guò)instanceof操作符來(lái)實(shí)現(xiàn)。

      另一方面,JavaScript并不檢查函數(shù)調(diào)用中的參數(shù)-這可以防止用一樣的命名和不同的參數(shù)來(lái)定義多態(tài)函數(shù)(并且讓編譯器選擇正確的簽名)。代之的是,JavaScript提供了一個(gè)Java 5風(fēng)格的函數(shù)范圍內(nèi)的argument對(duì)象-它允許你根據(jù)參數(shù)的類(lèi)型和數(shù)量的不同而實(shí)現(xiàn)一個(gè)不同的行為。
    三、 示例展示

      本文所附源碼列表1實(shí)現(xiàn)了一個(gè)計(jì)算器-它可以計(jì)算以一個(gè)逆向波蘭式標(biāo)志的表達(dá)式。該示例展示了本文中所介紹的主要技術(shù)并且也介紹了一些獨(dú)特的JavaScript特性的用法,例如在一個(gè)動(dòng)態(tài)函數(shù)調(diào)用中以一個(gè)數(shù)組元素的方式訪問(wèn)對(duì)象屬性。

      為了使列表1工作,我們需要另外準(zhǔn)備一些代碼-它們用于實(shí)例化該計(jì)算器對(duì)象并且調(diào)用evaluate方法:

    var e = new ArithmeticCalcuator([2,2,5,"add","mul"]);
    alert(e.evaluate());

      四、 AJAX組件授權(quán)

      所有的AJAX組件授權(quán)方案在今天被邏輯地分成兩組。具體地說(shuō),第一組用于與基于HTML的UI定義的無(wú)縫集成。第二組把HTML當(dāng)作一個(gè)UI定義語(yǔ)言以支持某種XML。在本文中,我們從第一組中來(lái)展示一種方法-雖然它存在于瀏覽器之中卻是類(lèi)似于JSP標(biāo)簽。這些瀏覽器特定的組件授權(quán)擴(kuò)展在IE情形下稱(chēng)作元素行為,而在最近版本的Firefox,Mozilla和Netscape 8情形下稱(chēng)作可擴(kuò)展的綁定。

      五、 定制標(biāo)簽

      Internet Explorer,從版本5.5開(kāi)始,支持定制的客戶端HTML元素的JavaScript授權(quán)。不象JSP標(biāo)簽,這些對(duì)象并沒(méi)有在服務(wù)器端被預(yù)處理到HTML中。而是,它們成為一標(biāo)準(zhǔn)HTML對(duì)象模型的合法擴(kuò)展,并且包括構(gòu)造控件在內(nèi)的一切事情,都是動(dòng)態(tài)地發(fā)生在客戶端的。同樣,基于Gecko-引擎的瀏覽器能夠用一個(gè)可重用功能動(dòng)態(tài)地裝飾任何現(xiàn)有的HTML元素。

      因此,我們有可能用具有HTML語(yǔ)法的方法、事件和屬性來(lái)構(gòu)建一個(gè)具有豐富的UI組件的庫(kù)。這樣的組件可以被自由地混合于標(biāo)準(zhǔn)HTML中。內(nèi)部地,這些組件將會(huì)與應(yīng)用程序服務(wù)器進(jìn)行通訊-以AJAX風(fēng)格。換句話說(shuō),你有可能(并且相對(duì)簡(jiǎn)單地)構(gòu)建自己的AJAX對(duì)象模型。
    這種IE風(fēng)味的方法被稱(chēng)為HTC或HTML組件;其Gecko版本被稱(chēng)為XBL-可擴(kuò)展的綁定語(yǔ)言(eXtensible Bindings Language)。為了實(shí)現(xiàn)本文目的,我們集中于討論IE。

      六、 輸入HTML組件-HTC

      HTC或HTML組件也被稱(chēng)作行為。它們被劃分為兩種類(lèi)型:一種是依附的行為-用一組屬性、事件和方法裝飾任何現(xiàn)有的HTML元素;另一種是元素行為-看上去象宿主頁(yè)面的定制的HTML標(biāo)簽的一個(gè)擴(kuò)展集合。依附的行為和元素行為一起提供了開(kāi)發(fā)組件和應(yīng)用程序的一種簡(jiǎn)單方案。在此,我們將展示一下最為綜合的情形-元素行為。

      數(shù)據(jù)綁定復(fù)選框控件

      為了展示元素行為,我們將構(gòu)建一個(gè)定制的數(shù)據(jù)綁定復(fù)選框。構(gòu)建這樣一個(gè)控件背后的基本原因在于,一個(gè)標(biāo)準(zhǔn)HTML復(fù)選框具有下面若干顯著的缺點(diǎn):

      ·需要應(yīng)用程序編碼來(lái)把"checked"屬性的值映射到商業(yè)域值,例如"Y[es]"/"N[o]","M[ale]"/"F[emale]",等等。HTML復(fù)選框使用"checked"屬性,而許多其它HTML控件使用的則是"value"屬性。

      ·需要應(yīng)用程序編碼來(lái)維持該控件的狀態(tài)(修改過(guò)的/未修改過(guò)的)。這實(shí)際上是在所有的HTML控件普遍存在的一個(gè)問(wèn)題。

      ·需要應(yīng)用程序編碼才能創(chuàng)建一個(gè)關(guān)聯(lián)標(biāo)簽-它應(yīng)該接受鼠標(biāo)點(diǎn)擊并相應(yīng)地改變?cè)搹?fù)選框的狀態(tài)。

      ·標(biāo)準(zhǔn)HTML復(fù)選框不支持"校驗(yàn)"事件以允許取消一個(gè)GUI行為,而這種要求可能存在于某些應(yīng)用程序中。

      現(xiàn)在,讓我們看一個(gè)正在構(gòu)建的該控件的用法示例,它的用法可能如下情形:

    <checkbox id="cbx_1" value="N" labelonleft="true"
    label="Show Details:" onValue="Y" offValue="N"/>

      另外,我們的控件將支持可取消的事件onItemChanging和通知事件onItemChanged。

      定義定制標(biāo)簽

      從結(jié)構(gòu)上講,一個(gè)定制標(biāo)簽是一個(gè)具有一個(gè)HTC擴(kuò)展名的文件-它在<PUBLIC:COMPONENT>和</PUBLIC:COMPONENT>標(biāo)志之間對(duì)它的屬性,方法和事件加以描述。

      為了定義一個(gè)定制CHECKBOX標(biāo)簽,我們創(chuàng)建一個(gè)如下列代碼片斷中的文件checkbox.htc-其中,第一行負(fù)責(zé)設(shè)置該組件的標(biāo)簽名:

    <PUBLIC:COMPONENT NAME="cbx" tagName="CHECKBOX">
    <PROPERTY NAME="value" GET="getValue" PUT="putValue" />
    //我們把組件的所有另外的屬性放在這里
    <METHOD NAME="show" />
    //我們把組件的所有另外的方法放在這里
    <EVENT NAME="onItemChanging" ID="onItemChanging"/>
    //我們把組件將向應(yīng)用程序激活的所有另外的事件放在這里
    <ATTACH EVENT="oncontentready" HANDLER="constructor" />
    //我們把組件自己處理的另外的事件放在這里
    <SCRIPT>
    //我們把所有的方法,屬性getters和setters和事件處理器放在這里
    </SCRIPT>
    </PUBLIC:COMPONENT>

      使用定制標(biāo)簽

      盡管HTC文件的內(nèi)容比較重要,但是這與其文件名是什么無(wú)關(guān)。值得注意的是,指向該HTC文件的URL需要被使用IMPORT指令指定-這必須在相應(yīng)的定制標(biāo)簽第一次出現(xiàn)之前(在頁(yè)面上)完成。下面是最簡(jiǎn)單的可能的頁(yè)面使用一個(gè)定制的復(fù)選框可能看上去的樣子-假定該頁(yè)面和HTC文件處理同一個(gè)文件夾下:

    <HTML xmlns:myns>
    <?IMPORT namespace="myns" implementation="checkbox.htc" >
    <BODY>
    <myns:checkbox id='cbx_1' label='Hello'/>
    </BODY>
    </HTML>

      請(qǐng)注意,定制CHECKBOX是怎樣在打開(kāi)的HTML標(biāo)簽中被映射到一個(gè)非缺省的命名空間"myns"的。這個(gè)IMPORT指令實(shí)現(xiàn)把HTC同步加載到瀏覽器的內(nèi)存并且還指示瀏覽器怎樣為適當(dāng)?shù)拿臻g實(shí)現(xiàn)名稱(chēng)確定的(HTC到命名空間的關(guān)聯(lián)可能是多對(duì)一的)。

      定制標(biāo)簽的構(gòu)造器

      最好的初始化HTC的方法是,一旦它被裝載就處理oncontentready事件。因此,我們可以定義處理器函數(shù)-為了概念清晰起見(jiàn),我們稱(chēng)之為構(gòu)造器:

    <ATTACH EVENT="oncontentready" HANDLER="constructor" />

      constructor()的邏輯是簡(jiǎn)單的:根據(jù)屬性labelonleft的值(見(jiàn)下面的屬性定義)按順序連接一個(gè)常規(guī)HTML復(fù)選框和HTML標(biāo)簽:

    function constructor() {
     //我們將把一個(gè)HTML復(fù)選框和標(biāo)簽添加到元素體
     //詳細(xì)情形見(jiàn)列表2
    }

      定義定制標(biāo)簽屬性

      為了定義屬性labelonleft,我們又在<PUBLIC:COMPONENT>部分加上一行:

    <PROPERTY NAME="labelonleft" VALUE="true"/>

      請(qǐng)注意,這個(gè)屬性并沒(méi)有包含getter和/或setter方法。屬性onValue和offValue不僅提供了從復(fù)選框狀態(tài)到一個(gè)商業(yè)值域的映射而且不需要getters和setters:

    <PROPERTY NAME="onValue" VALUE="true"/>
    <PROPERTY NAME="offValue" VALUE="false" />

      然而,屬性checked是用兩個(gè)getter和setter定義的:

    <PROPERTY NAME="checked" GET="getChecked" PUT="putChecked" />

      因此,我們?cè)冢糞CRIPT>部分建立了上面兩個(gè)方法的定義。正如你所見(jiàn),setter putChecked()-將在每次復(fù)選框狀態(tài)改變時(shí)激發(fā)-把value屬性設(shè)置為下面兩個(gè)變體之一:onValue或OffValue。請(qǐng)注意,putChecked()將不僅可由在復(fù)選框-宿主頁(yè)面中的腳本觸發(fā),而且也能通過(guò)在checkbox.htc中的相應(yīng)的任何賦值操作觸發(fā)。

    var _value;
    function putChecked( newValue ) {
     value = (newValue?onValue:offValue);
    }
    function getChecked(){
     return ( _value == onValue);
    }

    七、 為定制標(biāo)簽定義事件

      讓我們看一下onItemChanging和onItemChanged事件的定義以及這些事件是怎樣在value屬性的setter內(nèi)部被激發(fā)和處理的(見(jiàn)所附源碼中的列表2)。方法putValue()有幾個(gè)讓人感興趣的地方。首先,在分析CHECKBOX標(biāo)簽期間,可以調(diào)用這個(gè)方法-只要指定這個(gè)HTMLvalue屬性。這正解釋了為什么我們?yōu)榉菢?gòu)造對(duì)象建立一個(gè)單獨(dú)的邏輯分支-為把構(gòu)造過(guò)程與一個(gè)對(duì)用戶擊鍵的反應(yīng)區(qū)別開(kāi)來(lái)。其次,在此我們展示了定制事件onItemChanging的創(chuàng)建和處理-它允許應(yīng)用程序取消行為。請(qǐng)注意,通過(guò)這種方式,無(wú)論是擊鍵還是通過(guò)編程方式實(shí)現(xiàn)賦值都能達(dá)到取消的目的。

      事件取消

      為了取消事件,一個(gè)應(yīng)用程序應(yīng)該攔截該事件并且把event.returnValue設(shè)置為false。下面的代碼片斷展示了應(yīng)用程序是怎樣實(shí)現(xiàn)取消事件過(guò)程的:

    cbx_1::onItemChanging() {
    . . . . .
    if (canNotBeAllowed) {
     event.returnValue=false;
     . . . . .
    }

      如果事件沒(méi)被取消,putValue()把內(nèi)部的普通HTML復(fù)選框的checked屬性設(shè)置為每個(gè)相應(yīng)的當(dāng)前值-如果它等于onValue,這個(gè)內(nèi)部復(fù)選框?qū)⒈贿x中;如果它等于offValue(不存在第三種選擇),復(fù)選框不被選中(完整的列表見(jiàn)本文所附源碼中的列表2)。

      復(fù)選框的HTML內(nèi)幕

      我們控件的繪制是通過(guò)助理函數(shù)addLabel()和addCheckBox()來(lái)實(shí)現(xiàn)的并且從一個(gè)constructor()內(nèi)部調(diào)用。這些函數(shù)把HTML注入進(jìn)元素的innerHTML。這種注入式HTML的一種簡(jiǎn)化形式如下所示:

    <LABEL for=cb_{uniqueID}>Show Details:</LABEL>
    <INPUT id=cb_{uniqueID} type=checkbox />

      在此,uniqueID是一個(gè)由IE所生成的唯一的(在一個(gè)頁(yè)面內(nèi))字符串-它用來(lái)識(shí)別HTC的實(shí)例。

      八、 再封裝

      在我們的CHECKBOX中有一個(gè)缺點(diǎn)。按照我們建立它的方式,在constructor()期間被注入的HTML將隸屬于宿主該HTC的頁(yè)面的DOM。而且,全局的JavaScript變量like_value屬于它們所在的文檔的全局范圍。這是危險(xiǎn)的,因?yàn)槲覀兣既粫?huì)遇到命名沖突的可能性:最明顯的情形是使用同一個(gè)組件的多個(gè)實(shí)例。另外這還會(huì)導(dǎo)致一個(gè)可能性-我們的控件可能會(huì)偶然地用相同的名稱(chēng)參考其它對(duì)象,反之也如此。

      為簡(jiǎn)化起見(jiàn),需要建立一種專(zhuān)門(mén)的機(jī)制來(lái)為對(duì)象授權(quán)啟動(dòng)一個(gè)真正模塊化方法。幸好,HTC技術(shù)支持一種智能答案-viewLink。
     
      把一個(gè)控件聲明為封裝的最容易的方法是把一個(gè)額外聲明放到打開(kāi)和關(guān)閉的PUBLIC:COMPONENT標(biāo)簽之間:

    <PUBLIC:DEFAULTS viewLinkContent/>

      該控件立即就變成封裝性的;而且它有自己的HTML文檔樹(shù)-成為主文檔的原子組件。該對(duì)象的每個(gè)實(shí)例有它自己的實(shí)例值的集合并且只有公共方法和屬性能夠從外界代碼中加以存取。換句話說(shuō),該viewLink機(jī)制充分地啟動(dòng)了復(fù)雜的Web應(yīng)用程序的設(shè)計(jì)和實(shí)現(xiàn)-通過(guò)使用一種真正的OO的基于組件的方法。

      特別地,我們可以簡(jiǎn)化代碼-通過(guò)從內(nèi)部復(fù)選框和HTML標(biāo)簽的定義中刪除uniqueID后綴,因?yàn)槲覀儾辉贀?dān)心命名沖突。因此,我們可以替換下面這一行:

    eval( 'cb_'+uniqueID).checked = ( _value == onValue );

      用

    cb.checked = ( _value == onValue );

      并相應(yīng)地改變addCheckbox()和addLabel()。

      九、 結(jié)論

      既然AJAX競(jìng)賽剛剛開(kāi)始,那么就不存在什么AJAX標(biāo)準(zhǔn)并且沒(méi)有現(xiàn)成的你可以依賴以構(gòu)建你的應(yīng)用程序的可廣為接受的RAD工具。雖然軟件供應(yīng)商們可能還需要較長(zhǎng)一段時(shí)間來(lái)創(chuàng)建這種強(qiáng)健的開(kāi)發(fā)平臺(tái),AJAX熱心者已經(jīng)開(kāi)始著手準(zhǔn)備-通過(guò)一些良好定義的API把可重用的代碼塊封裝為商業(yè)組件。

      以這種方向?qū)Ш剑疚母爬薃JAX語(yǔ)言的OO"力量"-JavaScript。另外,還展示了一種可用的組件-授權(quán)策略-客戶端定制標(biāo)簽技術(shù)。我們?cè)趦H描述IE特定的定制標(biāo)簽的同時(shí),還另外提供了一個(gè)可下載的實(shí)例-適于Mozilla瀏覽器的可擴(kuò)展的綁定實(shí)例。
    posted on 2006-02-09 13:36 黑咖啡 閱讀(201) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): FrameWork

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    留言簿(2)

    隨筆分類(lèi)(67)

    文章分類(lèi)(43)

    Good Article

    Good Blogs

    Open Source

    最新隨筆

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲成a人片在线看| 91在线视频免费看| 中国一级特黄的片子免费| 菠萝菠萝蜜在线免费视频| 免费网站观看WWW在线观看| 亚洲视频在线不卡| 国产亚洲精品a在线观看app| 日本免费人成黄页网观看视频| 99re6在线视频精品免费下载 | 中文字幕无码毛片免费看| jizzjizz亚洲日本少妇| 亚洲一区二区三区久久| 67pao强力打造67194在线午夜亚洲| 在线亚洲精品福利网址导航| 免费一级特黄特色大片在线观看 | 亚洲第一福利网站| 久久精品国产亚洲AV不卡| 国产一卡二卡≡卡四卡免费乱码| 成年免费大片黄在线观看岛国| 24小时日本韩国高清免费| 久久久久久国产精品免费免费男同 | a在线观看免费视频| 72pao国产成视频永久免费| 97在线视频免费| 18女人腿打开无遮掩免费| 成人免费大片免费观看网站| 女人18毛片水最多免费观看 | 成人黄网站片免费视频| 中文字幕亚洲免费无线观看日本| 在线视频精品免费| 国产成人免费a在线视频色戒| 亚洲人成无码www久久久| 亚洲精品蜜桃久久久久久| 亚洲一区二区成人| 亚洲狠狠婷婷综合久久蜜芽| 特级做a爰片毛片免费看| 久久99精品免费视频| 久久久久国色AV免费观看性色| 免费萌白酱国产一区二区| 亚洲Aⅴ无码专区在线观看q| 精品久久亚洲中文无码|