AngularJS入門知識之MVW類框架的編程思想探討
本文通過實(shí)現(xiàn)兩個(gè)簡單的業(yè)務(wù)需求,探討AngularJS和傳統(tǒng)的JavaScript控制DOM實(shí)現(xiàn)方式的差別,并嘗試?yán)斫?MVW此類框架在流行的Web前端開發(fā)中的編程思想。
這個(gè)需求很常見,比如,一個(gè)兩級菜單,在第一級別菜單項(xiàng)點(diǎn)擊時(shí)候,對應(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),相對代碼要精煉很多,只有HTML的版本即可。以上代碼,用到了AngularJS這些知識點(diǎn):
ng-click和ng-hide都是框架自帶的Directives(指令),前者相當(dāng)于給li標(biāo)簽提供了一個(gè)Event Handler,在該HTML元素(li)被點(diǎn)擊的時(shí)候,會執(zhí)行hide_child = !hide_child這個(gè)Expression(表達(dá)式)。我們先看一下ng-hide這個(gè)指令,它會根據(jù)賦值的表達(dá)式結(jié)果(布爾值)來控制該HTML元素是否要顯示(通過CSS實(shí)現(xiàn))。也就是說,如果hide_child這個(gè)變量如果是true,那么ul就會被隱藏,否則結(jié)果相反。
這里hide_child其實(shí)是$scope上的一個(gè)變量,對它的值的變更,也可以用controller控制器包裝一個(gè)方法來實(shí)現(xiàn),只不過現(xiàn)在的語句比較簡單,直接寫在了指令的賦值里面。
通過以上簡單的代碼分析,我們可以看到AngularJS兩個(gè)比較明顯的特點(diǎn):
1.通過指令和表達(dá)式對DOM的操作進(jìn)行了封轉(zhuǎn),只需簡單的代碼便可省去額外的JavaScript代碼
2.指令和表達(dá)式的應(yīng)用,只直接嵌套在HTML中的,這和jQuery推從的Unobtrusive JavaScript的代碼風(fēng)格有些背道而馳
我們先看另外一個(gè)需求,再詳細(xì)解釋上面的結(jié)論。
需求2:通過點(diǎn)擊div,觸發(fā)選擇form中的一個(gè)radio button
傳統(tǒng)的HTML Form元素,在如今的移動設(shè)備上,操作起來并不是十分友好。比如,Radio button單選框,在觸摸屏上,需要精確的位置定位,才能控制好這個(gè)組件,但是手指定位又很粗糙。常見的做法,是添加一個(gè)對應(yīng)的Label控件,但是文字本身占屏比例也并不理想,而且也不具備明確的信息傳達(dá)效果。所以,通常會間接操作一個(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è)解決方案中,我們同樣沒有涉及到額外的JavaScript代碼,并且多用了幾個(gè)指令。為了對比參照,我們只關(guān)心ng-click和ng-model這兩個(gè)指令的表達(dá)式。
我們先看一下input這個(gè)元素的ng-model指令,這里賦值的意思是,我們把模板上的input和$scope.model對象的option屬性進(jìn)行了關(guān)聯(lián),深入了解數(shù)據(jù)綁定可以參考Data Binding。這種指定關(guān)聯(lián),使得模板控件直接和數(shù)據(jù)Model進(jìn)行了綁定,并且這種綁定是雙向的。意味著,一旦用戶修改控件中的值(勾選radio input),對應(yīng)的Model對象就會重新賦值(model.option);同時(shí),如果Model對象的值發(fā)生了變化,模板中的input控件也會對應(yīng)反映變化。而這點(diǎn),在上述jQuery的實(shí)現(xiàn)中,其實(shí)是沒有做到的。
所以,這里通過AngularJS的數(shù)據(jù)綁定,點(diǎn)擊li元素間接完成觸發(fā)input的流程是這樣子的:
1.點(diǎn)擊li標(biāo)簽,給model.option賦值;
2.修改了Model對象,定位到對應(yīng)input控件(value的值為model.option那個(gè));
3.激活input控件的checked屬性
通過以上兩個(gè)案例,我們對Web前端的操作有了新的認(rèn)識。
首先,技術(shù)實(shí)現(xiàn)上,通過引入新的指令,表達(dá)式,數(shù)據(jù)綁定等概念,我們可以完全新的方式去操作DOM,而不僅僅局限在用戶和HTML組件交互操作上的JavaScript代碼的實(shí)現(xiàn)。這種思想的變化是巨大的。
從本世紀(jì)初,動態(tài)Web編程的興起開始,服務(wù)器端的編程技術(shù)一直在改進(jìn)。從一開始的CGI/PHP/ASP,由語言和平臺產(chǎn)生了.NET vs. Java,開發(fā)效率和軟件過程促進(jìn)了MVC框架/ORM/AOP等,性能和大數(shù)據(jù)帶來了NodeJS/NoSQL/Hadoop等,而瀏覽器前端的技術(shù)需求似乎沒有那么激進(jìn)過。一方面,通過服務(wù)器端和數(shù)據(jù)庫,大部分B/S模型的業(yè)務(wù)需求都能滿足;再者,瀏覽器本身存在不同平臺的差異性,對腳本語言和渲染技術(shù)的標(biāo)準(zhǔn)不兼容,以及運(yùn)算能力的欠缺和安全性的考慮。
在這種情況下,瀏覽器端的需求,大部分時(shí)候只需要考慮渲染頁面和簡單的用戶交互。HTML/DOM加上JavaSript/CSS就這樣成就了前端的主要工作。所以,以前是沒有前端工作師,只需要Web設(shè)計(jì)師的。慢慢對前端的要求多起來,jQuery成為使用程度最高的一個(gè)JavaScript操作DOM的封裝庫。而在這個(gè)階段,jQuery/JavaScript的主要任務(wù),仍然只是作為面向用戶瀏覽器終端呈現(xiàn)和交互的工具。
理解了jQuery的起源,我們不難發(fā)現(xiàn),以前追求的一些規(guī)則,譬如Unobtrusive JavaScript,當(dāng)時(shí)局限于實(shí)現(xiàn)的手段和方式,為了分離DOM和JavaScript代碼邏輯,我們優(yōu)先選擇了維護(hù)性更高的方式。前端對JavaScript的需求加大之后,出現(xiàn)了很多MVC/MVP的前端框架,以及AngularJS所謂的MVW(Model-View-Whatever),JavaScript和DOM一刀切的方式發(fā)生了變化。原先我們考慮界面顯示和用戶交互的直接操作,現(xiàn)在我們有了客戶端的數(shù)據(jù)綁定,豐富的指令,依賴注入,等待我們的將是全新的編程模型和思維方式。
相關(guān)文章
Angularjs Ng_repeat中實(shí)現(xiàn)復(fù)選框選中并顯示不同的樣式方法
今天小編就為大家分享一篇Angularjs Ng_repeat中實(shí)現(xiàn)復(fù)選框選中并顯示不同的樣式方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09angular2+nodejs實(shí)現(xiàn)圖片上傳功能
這篇文章主要介紹了angular2+nodejs實(shí)現(xiàn)圖片上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03AngularJS基礎(chǔ) ng-model-options 指令簡單示例
本文主要介紹AngularJS ng-model-options 指令,這里對ng-model-options指令的基本資料進(jìn)行整理,有需要的小伙伴可以參考下2016-08-08Angular+ionic實(shí)現(xiàn)折疊展開效果的示例代碼
這篇文章主要介紹了Angular+ionic實(shí)現(xiàn)折疊展開效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Angular.js中下拉框?qū)崿F(xiàn)渲染html的方法
這篇文章主要給大家介紹了關(guān)于在Angular.js中下拉框?qū)崿F(xiàn)渲染html的方法,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-06-06AngularJS實(shí)現(xiàn)Model緩存的方式
這篇文章主要介紹了AngularJS實(shí)現(xiàn)Model緩存的方式,分享了多種AngularJS實(shí)現(xiàn)Model緩存的方法,感興趣的小伙伴們可以參考一下2016-02-02