哪個(gè)框架更適合將不同的思想和工具進(jìn)行對(duì)比,是一種更好地理解它們的方式。在本文中,我首先將列舉在創(chuàng)建web應(yīng)用程序時(shí)需要重復(fù)進(jìn)行的各項(xiàng)任務(wù),隨后為你展現(xiàn)Backbone和Angular將如何幫助你完成這些工作。 轉(zhuǎn)載請(qǐng)注明出處:http://www./2015/03/09/2015_backbone_angular/ 我們所嘗試解決的問(wèn)題作為web開(kāi)發(fā)者來(lái)說(shuō),我們的大部分工作都可以歸結(jié)于以下的某個(gè)類別中:
backbone做了些什么首先讓我們看看Backbone為解決這些問(wèn)題提供了哪些功能: ![]() 將最原始的Backbone與Angular直接進(jìn)行對(duì)比有些不太公平,因此在本文中所指的Backbone實(shí)際上是Backbone + Marionette + 插件的這套組合。
業(yè)務(wù)邏輯Backbone應(yīng)用程序中的很大一部分業(yè)務(wù)邏輯由模型(model)和集合(collection)負(fù)責(zé)實(shí)現(xiàn),這些對(duì)象往往對(duì)應(yīng)著服務(wù)端后臺(tái)的資源,它們將包含視圖顯示所必須的內(nèi)容。 由于使用者必須擴(kuò)展Backbone.Model和Backbone.Collection對(duì)象,因此造成了許多額外的復(fù)雜性。 首先,Backbone使用POJO(簡(jiǎn)單JavaScript對(duì)象)和Backbone model對(duì)象兩種方式表現(xiàn)領(lǐng)域?qū)ο蟆T陲@示模板(template)、或是與服務(wù)端交互時(shí)需要使用POJO,而在需要使用可觀察(observable)屬性時(shí)(例如需要建立數(shù)據(jù)綁定的時(shí)候),則需要使用Backbone模型。 其次,Backbone推薦你使用不可變對(duì)象。由于Backbone不支持對(duì)函數(shù)進(jìn)行觀察,因此每次有某個(gè)屬性發(fā)生改變時(shí),與之相對(duì)應(yīng)的推斷(computed)屬性必須被重置。這就為你的應(yīng)用增加了許多額外的復(fù)雜性,也使得最終產(chǎn)生的代碼難以理解和測(cè)試。除此之外,所有的依賴項(xiàng)必須以(”change:sourceProperty, this.recalculateComputedProperty)的形式顯式地進(jìn)行指定。 構(gòu)建DOMBackbone使用模板引擎構(gòu)建DOM。雖然從理論上說(shuō),你可以選擇你所中意的引擎,但基本上在大型應(yīng)用程序中都會(huì)在Mustache和Handlebars這兩者之間進(jìn)行選擇。Backbone中的模板定義通常不包含邏輯,并且多數(shù)是基于字符串的,不過(guò)這兩點(diǎn)也并非必需。 視圖邏輯將視圖邏輯劃分為命令式與聲明式邏輯是一種由來(lái)已久的方式(可以追溯到原始的MVC模式)。事件處理配置和數(shù)據(jù)綁定屬于聲明式,而事件處理本身則是屬于命令式。不過(guò)Backbone并沒(méi)有為這兩者劃分出一條清晰的界限,它們都由Backbone.View對(duì)象處理。 在模型與視圖間進(jìn)行同步由于Backbone在本質(zhì)上追求最簡(jiǎn)化,因此它本身并沒(méi)有為數(shù)據(jù)綁定提供支持。這一點(diǎn)對(duì)于小型項(xiàng)目來(lái)說(shuō)或許不是一個(gè)問(wèn)題,畢竟你可以選擇讓視圖負(fù)責(zé)對(duì)模型和DOM進(jìn)行同步。但當(dāng)應(yīng)用程序的功能開(kāi)始不斷增加時(shí),這種方式就很容易漸漸失控。 好在如今已經(jīng)有各種各樣的插件(例如Backbone.Sticklt)能夠幫助Backbone解決這一問(wèn)題了,因此你可以不用再理會(huì)瑣碎的模型-視圖同步操作,而是專注于復(fù)雜的交互工作。這些插件中的大多數(shù)都可以使用簡(jiǎn)單的JavaScript進(jìn)行配置,因此使用者可以在它的基礎(chǔ)之上創(chuàng)建一個(gè)抽象層,以滿足你應(yīng)用程序的需求。 在Backbone中使用數(shù)據(jù)綁定的一個(gè)缺點(diǎn)就是它們依賴于可觀察屬性,而另一方面,模板引擎又是使用POJO實(shí)現(xiàn)的。由于同時(shí)存在著兩種與DOM交互的方式,經(jīng)常會(huì)造成代碼的重復(fù)。 管理復(fù)雜的UI交互操作所有的UI交互操作都可以劃分為簡(jiǎn)單交互操作(使用觀察者同步(Observer Synchronization)方式進(jìn)行管理)和復(fù)雜交互操作(必須使用流同步(Flow Synchronization)方式)兩種類別。 如前文所述,簡(jiǎn)單交互操作是通過(guò)使用數(shù)據(jù)綁定和事件處理函數(shù)的Backbone.View進(jìn)行處理的。由于Backbone本身沒(méi)有硬性規(guī)定處理復(fù)雜UI交互的解決方案,你可以隨意選擇最適合你的應(yīng)用的方式。有些人選擇使用Backbone.View作為解決方案,但我建議你不要這么做,因?yàn)檫@種方式會(huì)造成Backbone.View的職責(zé)過(guò)多。我會(huì)傾向于使用主動(dòng)控制顯示(Supervising Presenter)模式管理復(fù)雜的交互操作。 管理狀態(tài)和路由Backbone包含了一個(gè)非常簡(jiǎn)單的路由器的實(shí)現(xiàn),但它并不支持管理視圖和應(yīng)用狀態(tài)的功能,必須要手動(dòng)實(shí)現(xiàn)這些功能。因此在實(shí)際應(yīng)用中經(jīng)常會(huì)選擇使用其它類庫(kù)(例如router.js),而不是它自帶的路由器。 創(chuàng)建與連接組件在Backbone中,你可以自由選擇最適合你的應(yīng)用的方式創(chuàng)建并連接組件。這種方式的缺陷在于你必須編寫(xiě)大量的樣板代碼,而且為了保持代碼的合理組織,必須始終遵循良好的代碼規(guī)范。 Angular做了什么現(xiàn)在讓我們來(lái)比較一下,看看Angular是如何解決這些問(wèn)題的。 ![]()
業(yè)務(wù)邏輯由于Angular沒(méi)有使用可觀察屬性,因此在實(shí)現(xiàn)模型時(shí)沒(méi)有這方面的限制。你不需要擴(kuò)展某個(gè)類、或者遵循某個(gè)接口,而是可以自由地選擇你喜歡的方式(包括使用現(xiàn)有的Backbone模型)。在實(shí)際開(kāi)發(fā)中,多數(shù)開(kāi)發(fā)者選擇使用簡(jiǎn)單的JavaScript對(duì)象(POJO),這種方式有以下優(yōu)點(diǎn):
模板與視圖由于Angular沒(méi)有使用可觀察屬性,因此在實(shí)現(xiàn)模型時(shí)沒(méi)有這方面的限制。你不需要擴(kuò)展某個(gè)類、或者遵循某個(gè)接口,而是可以自由地選擇你喜歡的方式(包括使用現(xiàn)有的Backbone模型)。在實(shí)際開(kāi)發(fā)中,多數(shù)開(kāi)發(fā)者選擇使用簡(jiǎn)單的JavaScript對(duì)象(POJO),這種方式有以下優(yōu)點(diǎn): 所有的領(lǐng)域?qū)ο蠖疾灰蕾囉谌魏翁囟ǖ目蚣?,因而更容易在不同的?yīng)用中重用。 構(gòu)建DOMBackbone將DOM的構(gòu)建與視圖邏輯進(jìn)行了清晰地分離,前者使用模板引擎實(shí)現(xiàn),而后者則使用數(shù)據(jù)綁定與命令式的DOM更新操作實(shí)現(xiàn)。與之相反,Angular并未將這兩者進(jìn)行區(qū)分,它使用相同的機(jī)制和指令(directive)構(gòu)建DOM,并定義聲明式的視圖行為。 視圖邏輯Angular對(duì)聲明式與命令式的視圖邏輯進(jìn)行了清晰的劃分,前者由視圖處理,而后者由控制器負(fù)責(zé)。 這種劃分看起來(lái)似乎有些刻意,但它確實(shí)是非常重要的。 首先,這種方式清晰地指出了哪些部分需要進(jìn)行單元測(cè)試。嵌入在模板中的聲明式邏輯(例如ng-repeat)無(wú)需進(jìn)行單元測(cè)試,反之,為控制器編寫(xiě)單元測(cè)試通常是個(gè)好主意。 其次,所有的依賴都是單向的,即視圖依賴于控制器,因此控制器并不了解視圖或DOM的任何邏輯。這種方式促進(jìn)了代碼重用,也簡(jiǎn)化了單元測(cè)試。與之相反,Backbone.View經(jīng)常需要對(duì)DOM節(jié)點(diǎn)進(jìn)行操作,隨后使用模板引擎對(duì)頁(yè)面中的很大一部分進(jìn)行重新渲染。 在模型與視圖間進(jìn)行同步Angular包含了原生的數(shù)據(jù)綁定功能,與大廈多數(shù)其它客戶端框架所不同的是,它并不依賴于可觀察屬性,而是使用了臟檢查(dirty checking)方式。
Angular的臟檢查方式有著以下一些優(yōu)點(diǎn): 模型本身不會(huì)意識(shí)到它已經(jīng)成為一個(gè)被觀察的對(duì)象。 在與第三方組件或類庫(kù)集成的時(shí)候,你必須保證Angular能夠響應(yīng)它們對(duì)你的模型的任何改變。 管理復(fù)雜的UI交互操作如前文所述,控制器將負(fù)責(zé)實(shí)現(xiàn)UI元素的命令式邏輯。除此之外,還可以將控制器實(shí)現(xiàn)為一種主動(dòng)控制顯示模式,以協(xié)調(diào)復(fù)雜的UI交互。
管理狀態(tài)和路由與Backbone類似,Angular自帶的路由器功能非?;A(chǔ),并不適合于創(chuàng)建實(shí)際的應(yīng)用。令人欣慰的是,AngularUI Router項(xiàng)目填補(bǔ)了這一空白。它能夠管理應(yīng)用狀態(tài)、視圖,并且支持嵌套視圖。換句話說(shuō),它能夠滿足你對(duì)路由器的全部功能需求。當(dāng)然,和Backbone的情況一樣,你并非只有這一種選擇,你也可以選擇其它的路由功能類庫(kù)(例如router.js)。 創(chuàng)建與連接組件Angular包含了一個(gè)IoC容器,它與通常意義上的依賴注入方法非常相似,這就要求你必須編寫(xiě)模塊化的代碼。這種方式能夠改善代碼的可重用性和可測(cè)試性,也使你免于編寫(xiě)大量的樣板代碼。它的負(fù)面影響在于一方面增加了使用的復(fù)雜度,一方面削弱了對(duì)組件創(chuàng)建過(guò)程的可控程度。 總結(jié)本文簡(jiǎn)單地介紹了Backbone和Angular如何處理我們?cè)趧?chuàng)建web應(yīng)用時(shí)所遇到的各種問(wèn)題。這兩個(gè)框架在某些問(wèn)題的處理上使用了截然不同的方案,Backbone在顯示模板、創(chuàng)建數(shù)據(jù)綁定和連接組件方面給使用者更多的選擇。與之相反,Angular為這些問(wèn)題提供了規(guī)定的方案,不過(guò)在創(chuàng)建模型與控制器方面的限制就比較少一些。 謝謝!轉(zhuǎn)載請(qǐng)注明出處:http://www./2014/07/29/2014_angularjs_1/ |
|
來(lái)自: 看見(jiàn)就非常 > 《tip》