AngularJS入門(mén)知識(shí)之MVW類(lèi)框架的編程思想探討
本文通過(guò)實(shí)現(xiàn)兩個(gè)簡(jiǎn)單的業(yè)務(wù)需求,探討AngularJS和傳統(tǒng)的JavaScript控制DOM實(shí)現(xiàn)方式的差別,并嘗試?yán)斫?MVW此類(lèi)框架在流行的Web前端開(kāi)發(fā)中的編程思想。
這個(gè)需求很常見(jiàn),比如,一個(gè)兩級(jí)菜單,在第一級(jí)別菜單項(xiàng)點(diǎn)擊時(shí)候,對(duì)應(yīng)的子菜單項(xiàng)目應(yīng)該顯示或隱藏。
jQuery的實(shí)現(xiàn):
<!-- html -->
<ul class="parent">
<li class="parent_item">
Item 1
<ul class="child">
<li class="child_item">Item child 1</li>
</ul>
</li>
</ul>
// javascript
$('li.parent_item').click(function(){
$(this).children('ul.child').toggle();
})
AngularJS的實(shí)現(xiàn):
<!-- html -->
<ul>
<li ng-click="hide_child = !hide_child">
Item 1
<ul ng-hide="hide_child">
<li>Item child 1</li>
</ul>
</li>
</ul>
傳統(tǒng)操作DOM的方式,不再贅述。AngularJS的實(shí)現(xiàn),相對(duì)代碼要精煉很多,只有HTML的版本即可。以上代碼,用到了AngularJS這些知識(shí)點(diǎn):
ng-click和ng-hide都是框架自帶的Directives(指令),前者相當(dāng)于給li標(biāo)簽提供了一個(gè)Event Handler,在該HTML元素(li)被點(diǎn)擊的時(shí)候,會(huì)執(zhí)行hide_child = !hide_child這個(gè)Expression(表達(dá)式)。我們先看一下ng-hide這個(gè)指令,它會(huì)根據(jù)賦值的表達(dá)式結(jié)果(布爾值)來(lái)控制該HTML元素是否要顯示(通過(guò)CSS實(shí)現(xiàn))。也就是說(shuō),如果hide_child這個(gè)變量如果是true,那么ul就會(huì)被隱藏,否則結(jié)果相反。
這里hide_child其實(shí)是$scope上的一個(gè)變量,對(duì)它的值的變更,也可以用controller控制器包裝一個(gè)方法來(lái)實(shí)現(xiàn),只不過(guò)現(xiàn)在的語(yǔ)句比較簡(jiǎn)單,直接寫(xiě)在了指令的賦值里面。
通過(guò)以上簡(jiǎn)單的代碼分析,我們可以看到AngularJS兩個(gè)比較明顯的特點(diǎn):
1.通過(guò)指令和表達(dá)式對(duì)DOM的操作進(jìn)行了封轉(zhuǎn),只需簡(jiǎn)單的代碼便可省去額外的JavaScript代碼
2.指令和表達(dá)式的應(yīng)用,只直接嵌套在HTML中的,這和jQuery推從的Unobtrusive JavaScript的代碼風(fēng)格有些背道而馳
我們先看另外一個(gè)需求,再詳細(xì)解釋上面的結(jié)論。
需求2:通過(guò)點(diǎn)擊div,觸發(fā)選擇form中的一個(gè)radio button
傳統(tǒng)的HTML Form元素,在如今的移動(dòng)設(shè)備上,操作起來(lái)并不是十分友好。比如,Radio button單選框,在觸摸屏上,需要精確的位置定位,才能控制好這個(gè)組件,但是手指定位又很粗糙。常見(jiàn)的做法,是添加一個(gè)對(duì)應(yīng)的Label控件,但是文字本身占屏比例也并不理想,而且也不具備明確的信息傳達(dá)效果。所以,通常會(huì)間接操作一個(gè)區(qū)域比較大的div或者li標(biāo)簽。
jQuery的實(shí)現(xiàn):
<!-- html -->
<ul>
<li class="selection">
<input type="radio"
id="option1" />
<label for="option1">option 1</label>
</li>
</ul>
// javascript
$('li.selection').click(function(){
$(this).children('input[type="radio"]').click();
})
AngularJS的實(shí)現(xiàn):
<!-- html -->
<ul>
<li ng-repeat="option in options"
ng-click="model.option = option.value"
ng-class="{active: model.option == option.value}" >
<input type="radio"
ng-model="model.option"
value="{{option.value}}"
id="option1" />
<label for="option1">option 1</label>
</li>
</ul>
在這個(gè)解決方案中,我們同樣沒(méi)有涉及到額外的JavaScript代碼,并且多用了幾個(gè)指令。為了對(duì)比參照,我們只關(guān)心ng-click和ng-model這兩個(gè)指令的表達(dá)式。
我們先看一下input這個(gè)元素的ng-model指令,這里賦值的意思是,我們把模板上的input和$scope.model對(duì)象的option屬性進(jìn)行了關(guān)聯(lián),深入了解數(shù)據(jù)綁定可以參考Data Binding。這種指定關(guān)聯(lián),使得模板控件直接和數(shù)據(jù)Model進(jìn)行了綁定,并且這種綁定是雙向的。意味著,一旦用戶修改控件中的值(勾選radio input),對(duì)應(yīng)的Model對(duì)象就會(huì)重新賦值(model.option);同時(shí),如果Model對(duì)象的值發(fā)生了變化,模板中的input控件也會(huì)對(duì)應(yīng)反映變化。而這點(diǎn),在上述jQuery的實(shí)現(xiàn)中,其實(shí)是沒(méi)有做到的。
所以,這里通過(guò)AngularJS的數(shù)據(jù)綁定,點(diǎn)擊li元素間接完成觸發(fā)input的流程是這樣子的:
1.點(diǎn)擊li標(biāo)簽,給model.option賦值;
2.修改了Model對(duì)象,定位到對(duì)應(yīng)input控件(value的值為model.option那個(gè));
3.激活input控件的checked屬性
通過(guò)以上兩個(gè)案例,我們對(duì)Web前端的操作有了新的認(rèn)識(shí)。
首先,技術(shù)實(shí)現(xiàn)上,通過(guò)引入新的指令,表達(dá)式,數(shù)據(jù)綁定等概念,我們可以完全新的方式去操作DOM,而不僅僅局限在用戶和HTML組件交互操作上的JavaScript代碼的實(shí)現(xiàn)。這種思想的變化是巨大的。
從本世紀(jì)初,動(dòng)態(tài)Web編程的興起開(kāi)始,服務(wù)器端的編程技術(shù)一直在改進(jìn)。從一開(kāi)始的CGI/PHP/ASP,由語(yǔ)言和平臺(tái)產(chǎn)生了.NET vs. Java,開(kāi)發(fā)效率和軟件過(guò)程促進(jìn)了MVC框架/ORM/AOP等,性能和大數(shù)據(jù)帶來(lái)了NodeJS/NoSQL/Hadoop等,而瀏覽器前端的技術(shù)需求似乎沒(méi)有那么激進(jìn)過(guò)。一方面,通過(guò)服務(wù)器端和數(shù)據(jù)庫(kù),大部分B/S模型的業(yè)務(wù)需求都能滿足;再者,瀏覽器本身存在不同平臺(tái)的差異性,對(duì)腳本語(yǔ)言和渲染技術(shù)的標(biāo)準(zhǔn)不兼容,以及運(yùn)算能力的欠缺和安全性的考慮。
在這種情況下,瀏覽器端的需求,大部分時(shí)候只需要考慮渲染頁(yè)面和簡(jiǎn)單的用戶交互。HTML/DOM加上JavaSript/CSS就這樣成就了前端的主要工作。所以,以前是沒(méi)有前端工作師,只需要Web設(shè)計(jì)師的。慢慢對(duì)前端的要求多起來(lái),jQuery成為使用程度最高的一個(gè)JavaScript操作DOM的封裝庫(kù)。而在這個(gè)階段,jQuery/JavaScript的主要任務(wù),仍然只是作為面向用戶瀏覽器終端呈現(xiàn)和交互的工具。
理解了jQuery的起源,我們不難發(fā)現(xiàn),以前追求的一些規(guī)則,譬如Unobtrusive JavaScript,當(dāng)時(shí)局限于實(shí)現(xiàn)的手段和方式,為了分離DOM和JavaScript代碼邏輯,我們優(yōu)先選擇了維護(hù)性更高的方式。前端對(duì)JavaScript的需求加大之后,出現(xiàn)了很多MVC/MVP的前端框架,以及AngularJS所謂的MVW(Model-View-Whatever),JavaScript和DOM一刀切的方式發(fā)生了變化。原先我們考慮界面顯示和用戶交互的直接操作,現(xiàn)在我們有了客戶端的數(shù)據(jù)綁定,豐富的指令,依賴(lài)注入,等待我們的將是全新的編程模型和思維方式。
- AngularJS 2.0入門(mén)權(quán)威指南
- AngularJS入門(mén)教程之學(xué)習(xí)環(huán)境搭建
- Angularjs 基礎(chǔ)入門(mén)
- angularJS 入門(mén)基礎(chǔ)
- AngularJS快速入門(mén)
- AngularJs 60分鐘入門(mén)基礎(chǔ)教程
- AngularJS入門(mén)教程(二):AngularJS模板
- AngularJS入門(mén)心得之directive和controller通信過(guò)程
- AngularJS入門(mén)(用ng-repeat指令實(shí)現(xiàn)循環(huán)輸出
- Angular開(kāi)發(fā)者指南之入門(mén)介紹
相關(guān)文章
angular動(dòng)態(tài)刪除ng-repaeat添加的dom節(jié)點(diǎn)的方法
本篇文章主要介紹了angular動(dòng)態(tài)刪除ng-repaeat添加的dom節(jié)點(diǎn)的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-07-07
淺談Angularjs link和compile的使用區(qū)別
下面小編就為大家?guī)?lái)一篇淺談Angularjs link和compile的使用區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
詳解AngularJS Filter(過(guò)濾器)用法
這篇文章主要介紹了AngularJS的filter,中文名“過(guò)濾器”是用來(lái)過(guò)濾變量的值,或者格式化輸出,得到自己所期望的結(jié)果或格式的東東,的相關(guān)資料,需要的朋友可以參考下2015-12-12
Angular8 簡(jiǎn)單表單驗(yàn)證的實(shí)現(xiàn)示例
這篇文章主要介紹了Angular8 簡(jiǎn)單表單驗(yàn)證的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
AngularJS學(xué)習(xí)第一篇 AngularJS基礎(chǔ)知識(shí)
這篇文章主要介紹了AngularJS學(xué)習(xí)第一篇,分享了有關(guān)AngularJS的基礎(chǔ)知識(shí),主要包括指令、過(guò)濾器等,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
angularjs實(shí)現(xiàn)對(duì)表單輸入改變的監(jiān)控(ng-change和watch兩種方式)
這篇文章主要介紹了angularjs通過(guò)ng-change和watch兩種方式實(shí)現(xiàn)對(duì)表單輸入改變的監(jiān)控,需要的朋友可以參考下2018-08-08
AngularJS過(guò)濾器filter用法總結(jié)
這篇文章主要介紹了AngularJS過(guò)濾器filter用法,結(jié)合實(shí)例形式較為詳細(xì)的總結(jié)分析了過(guò)濾器filter的功能、分類(lèi)、使用技巧及自定義過(guò)濾器的實(shí)現(xiàn)方法,需要的朋友可以參考下2016-12-12
AngularJS基礎(chǔ)知識(shí)筆記之過(guò)濾器
在我們開(kāi)發(fā)中經(jīng)常需要在頁(yè)面顯示給用戶的信息需要一定處理格式化,才能顯示給用戶。比如時(shí)間本地化,或者yyyy-MM-dd HH:mm:ss格式,數(shù)字精度格式化,本地化,人名格式化等等。在angularjs中為我們提供了叫filter的指令,讓我們能夠很輕易就能做到著一些列的功能2015-05-05

