第190期 / August 8, 2013

研發新視界

分享到臉書!分享到維特!分享到噗浪!分享到Google+!分享到微博!轉寄友人友善列印

AngularJS初探

作者/江彥伯

[發表日期:2013/7/5]

前言

相信Web應用程式的開發人員對於JavaScript一定都不陌生,JavaScript可以在前端就幫網頁做一些處理,不需要每項操作都要透過網路傳輸到後端伺服器處理後再回傳到使用者前端畫面,一方面可以減少伺服器的負擔,另一方面可以提高執行的效率與即時性。然而早期開發JavaScript必須要寫很多的程式才能對網頁上的文件物件模型(DOM)做處理。為了解決這個問題,之後就陸陸續續有人開發出各式各樣的JavaScript Framework(框架)來減少開發所費的功。目前最受歡迎的就是jQuery,它提供了很多API方便開發人員對DOM做複雜的處理。

而本篇要介紹另一個由Google所開發的JavaScript Framework:AngularJS,AngularJS最大的特點就是在HTML裡面的標籤(Tag)加入AngularJS特有的屬性(Attribute),也就是所謂的宣告式語法 (Directives Syntax),賦予HTML更多更強大的功能,透過AngularJS的一些功能可以大幅減少開發時所需要寫的程式。此外,AngularJS是建立在MVC的設計模式(Design Pattern)之下,這個框架將模型(Model)檢視(View)控制器(Controller)做了一個很好的分離,可以讓Web程式更好維護及理解。

一般來說開發Web應用程式的過程當中最常做的莫過於對於後端資料的處理,而對於資料的處理不外乎就是新增、刪除、修改、查詢。AngularJS最大的功用及目的就在於我們可以把資料搬到前端,然後透過設計好的HTML模板(Template)來呈現及處理,像是它可以即時的對資料作計算和篩選過濾(Filter)和排序,此外它也提供了雙向資料繫結(Two Way Data-Binding)特性,讓前端資料的處理可以即時呈現。AngularJS處理資料是用JSON格式,後端可以將資料轉換成JSON格式,然後經由Web Service的方式送到前端作處理。

下面會介紹一些AngularJS的基本用法,包含如何用宣告式語法賦予HTML更強大的功能,另外會有一個對資料表做篩選、排序、新增、刪除、編輯的範例,讓大家對於AngularJS有初步的概念。

AngularJS介紹

首先先上http://angularjs.org/下載最新版本,然後將它加入到需要用到的網頁上,或是直接連接此工具的網址。然後在< html >的標籤上加上ng-app的屬性,如此一來AngularJS就可以作用於這一整個頁面,這就是AngularJS所謂的宣告式語法,當標籤裡面被宣告了AngularJS的屬性,被這個標籤所包起來的部份就可以利用被宣告的這個屬性。以下是個簡單的範例:

結果會是


這個範例是在一個TextBox加上ng-model的屬性,而這個屬性也就是MVC裡面所代表的資料模型(Model),而這個模型的名稱就是這個屬性的值”Name”。 {{Name}}中的兩組大括弧是用來標記資料繫結(data-binding),而中間的Name就是呈現的資料,此外也可以在標記中間直接做運算。在輸入TextBox的過程當中會發現輸入的文字會即時的顯示在下方,這就是所謂的雙向資料繫結(Two Way Data-Binding)的神奇效果,因為在輸入的同時也會去同步更新資料模型(Model),而當資料模型(Model)被更新的同時也會同步更新檢視(View)。

接下來看看如何將資料利用AngularJS繫結到table裡面,首先建立控制器(Controller),並且建立資料。AngularJS所存取的資料必須是JSON格式,這裡用的資料是NorthWind裡的客戶資料。

上圖為js/controllers.js的內容,接著下面程式碼會把資料繫結到前端


從上圖可以看到< table >的標籤裡加了ng-controller的屬性,而這個屬性的值CustomerListCtrl就可以連結到控制器(Controller),由於ng-controller是宣告在< table >這個標籤裡,所以CustomerListCtrl這個控制器就只能在< table >這個標籤內做使用,如果要擴大到< table >以外的地方都可以使用,那就要將ng-controller宣告在更上一個層級的標籤,例如裡面。由於資料模型(Model)Customers是屬於$scope下的物件,所以才可以在前端使用Customers。透過設計好的模板(Template)並設定ng-repeat繫結到CustomerListCtrl的Customers,就可以把Customers的資料一列一列的顯示出來,它的用法就有點像foreach裡面的表達式,而這個範例當中只顯示了CustomerID、CompanyName、Country、Phone四個欄位。執行的結果如下:



此外,AngularJS還提供了對資料篩選過濾和排序的功能,先分別建立一個用來篩選的輸入控制項及選擇排序依據的下拉式選單,並且分別宣告ng-model的屬性為query及orderProp,如此一來在輸入TextBox或選擇下拉式選單的同時就會把輸入的值及選項繫結到query及orderProp。建立完成後在ng-repeat的屬性裡加入filter和orderBy,並且把這兩個控制項ng-model的值繫結進去,當query及orderProp的值有變動的時候便會即時的反應在資料的呈現上。



如此一來,下方的資料就會依據輸入數值進行篩選及排序



以往要做到這樣的功能都必須在Textbox及下拉式選單裡面加入onchange事件,然後在onchange事件裡面在對DOM做很多的操作,但是使用了AngularJS就可以輕鬆做到這些功能,又不需要對DOM做大量的操作。

以上都是對資料的查詢,接下來會介紹如何對資料進行新增、刪除及修改。由於需要用到表單送出的功能,所以將所有的元件用< form >標籤包起來,為了讓< form >裡面的元件都可以使用CustomerListCtrl,就把ng-controller="CustomerListCtrl"搬到< form >裡面,並且加入ng-submit的屬性。當表單被送出(submit)時就會自動去執行對應的函式。然後在< table >裡面加入各個欄位輸入的控制項和新增的按鈕。


接著在CustomerListCtrl加入新增函式Add()的設計,這邊對這四個欄位做了檢核,當四個欄位都有值的時候就對Customers資料模型新增一筆資料,並且將這四個欄位清空。



執行結果如下:





由於這裡並沒有輸入任何篩選或者選擇排序的依據,所以新增的資料會直接被放在最後一列,但是如果有選擇排序的依據,新增的資料會被自動插入在排序後的所在位置。

接著在每列最後一欄加入刪除的按鈕,並且設定ng-click屬性,當刪除按鈕被按下就會去執行ng-click所設定的函式,然後把那列資料傳入函式中作為搜尋要被刪除資料的依據。


撰寫刪除的函式,先找到要刪除的那筆資料的索引(index),然後將該筆資料刪除。


執行結果:



最後加入編輯的功能,當按下編輯按鈕的時候編輯按鈕會變成儲存按鈕,並且那列的資料都會變成Textbox讓使用者修改;修改完後按下儲存按鈕後所有的TextBox都會變回無法修改,並且儲存按鈕變回編輯按鈕。在這邊可以利用雙向資料繫結(Two Way Data-Binding)的特性加上ng-hide及ng-show的屬性,可以輕鬆達到我們需要的效果。



在每個資料欄位放上顯示及編輯的控制項,並且設定ng-hide及ng-show的屬性,當ng-hide的屬性值為false的時候
裡面的內容就會顯示,反之< div >裡的內容就會隱藏;同樣的ng-show正好跟ng-hide相反,所以就把ng-show設定在編輯的TextBox裡面,透過編輯跟儲存按鈕的ng-click屬性設定該列資料的編輯屬性參數Editing,這樣就可以切換顯示編輯和非編輯狀態下的畫面。由於編輯每個欄位的TextBox都有設定ng-model的屬性,並將每個欄位的資料繫結到每列資料所對應到的欄位,所以其實修改TextBox內資料的同時也更新了該欄位的資料,儲存按鈕只是用來切換畫面的顯示。這就是雙向資料繫結(Two Way Data-Binding)與宣告式語法(Directives Syntax)最完美的結合,只要設定各個控制項的屬性,不用修改控制器(Controller)也可以完成這樣複雜的功能。執行的結果如下:




以上對資料的操作都只是在前端,若要對後端的資料作處理的話,AngularJS也有提供連接後台Web Service的API($http),這裡用到了AJAX的技術,而$http的使用方式跟jQuery非常的相似,詳細的使用方法可以上AngularJS的網站(http://docs.angularjs.org/api/)做查詢。

結語

AngularJS透過宣告式語法讓HTML延伸出許多功能,像是設計模板(Template)將控制器(Controller)和資料模型(Model)繫結上去,然後對繫結的資料做篩選排序,而這些好用的功能可以節省掉不少開發需要的功少寫很多的程式,讓HTML的可讀性更高,也更好維護,不過先決條件是要對AngularJS的各種功能及其使用方法要有一些基本的了解,才能夠靈活的運用。
AngularJS的雙向資料繫結(Two Way Data-Binding)特性可以讓使用者對資料的操作即時的呈現在前端的畫面上,如此一來就可以減少後台對資料處理的工夫,也可以減輕伺服器的負擔,不過也不宜將大量的資料送到前端作處理,畢竟前端的硬體資源也是有限的,過量的資料會造成前端系統資源不足的問題,所以在設計上面要特別的小心。另外,AngularJS對資料的處理都只在於前端,也就是使用者的記憶體裡,瀏覽器關掉資料就沒了,所以如果要將處理過後的資料寫回後端則需要另外開發將資料寫回後端的程式。

AngularJS的功能其實是建立在MVC的架構上,對於不熟悉MVC架構的開發者並不容易理解,需要先了解一下MVC架構,不過MVC架構已是現在常用主流的架構,對大部分開發者應該是很容易上手。舉例來說,如果有一個控制項在很多地方都會用到,開發時就只需要在這些地方加上檢視(View)的部份,控制器(Controller)和模型(Model)都可以共用,不用在每個地方都重複寫同樣的東西,如果需要修改控制器(Controller)的邏輯或是資料模型(Model)的內容也只需要修改一次就好。

AngularJS對於DOM的處理並不是那麼的擅長,因為AngularJS生來的目的本來就不是為了解決對DOM的處理,從它的架構及理念來看也不是。所以當設計需求必須要用到大量對DOM操作,而AngularJS的API又不能滿足設計需求時還是可以用jQuery來補足AngularJS。或是加上AngularUI(http://angular-ui.github.io/)這樣的plug-in來解決AngularJS所達不到的功能。
AngularJS是Goolge推出來的,應該有蠻多的愛用者,所以Goolge也會持續維護它。總結AngularJS的幾項特性:

1.宣告式語法 (Directives Syntax):以簡便的方式賦予HTML更多更強大的功能
2.模板(Template):將資料套用到設計好的模板
3.雙向資料繫結(Two Way Data-Binding):資料不須經過後端,於前端處理及運算並即時呈現
4.MVC架構:利於開發與維護的主流架構

從這幾點說明它是蠻值得推廣與採用的。不過,在利用AngularJS開發時還是必須注意幾點:

1.熟悉AngularJS的API及設計架構
2.AngularJS不適合用來做DOM的處理
3.熟悉MVC架構

以避免錯誤的使用AngularJS導致開發及維護上的困難。

AngularJS算是一項滿新的技術,應用方面雖然還沒像jQuery這麼廣泛,不過它的設計架構及理念來看算是一項非常有發展潛力的技術相信在未來會開發出更多的功能供使用者應用,值得所有Web程式開發人員好好學習的一門新技術。

參考資料

1.AngularJS官方網站 http://angularjs.org/
2.Book:AngularJS by Brad Green, Shyam Seshadri