iT邦幫忙

12

邊學AngularJS邊做Todo List (2) - Todo List 動起來

上次體驗過 AngularJS HelloWorld的範例之後,相信大家能夠體驗到AngularJS 相向互動的便利性,不需要寫太多的code,馬上就能有即時互動的能力。

這次,我們要開始進入用AngularJS來做Todo List。

今天我們的目標是做出一個可以輸入待辦事項的UI,並且可以新增待辦事項到Todo List當中。
【製作Todo List的Layout】

我們先把需要的Layout做出來,HTML碼如下:

<html ng-app>
  
    <meta charset="utf-8">  
    <title>邊學AngularJS邊做Todo List </title>
    <script type="text/javascript" src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
  
  
      <h1>Todo List</h1>
      <form>
        <input type="text" name="newItem" />
        <input type="submit" id="submit" value="新增" />
      </form>
      <ul>
        <li></li>
      </ul>
  

和上次Hello World的程式一樣,我們在 tag的地方加上一個ng-app指令(derective),讓AngularJS可以辨識出這是一個AngularJS的應用程式。

AngularJS提供了許多指令,這些指令可以教會HTML新的種種把戲,進而強化HTML在Web Application上的能力。除了ng-app之外,上次我們也看到了ng-model(作為資料綁定、可以雙向互動的資料模型),今天我們還會用到ng-repeat作為迭代器,以及ng-submit這個(監聽submit事件的指令),詳細的作用,稍後就能看到。

(有興趣深入的,可以看這篇 http://docs.angularjs.org/guide/directive

我們在HTML加入一個 <form> ,裡面有一個文字框(<input>),以及一個「新增」的 submit 按鈕。

另外準備一個<ul>,裡面準備用<li>來放新增的待辦事項。

Layout的規劃大致如此,接下來我們就要討論如何讓資料由輸入框跑到下面的列表中。

【Controller登場】

一般的網站,會用資料庫來處理資料的儲存和存取,不過為了先專注在AngularJS上面,我們就先用簡化的作法,先用二個JavaScript物件來處理資料,一個是 newItem,用來存放新增的待辦事項(字串型態),另外一個是 todoList,用來存放所有的待辦事項。

那麼這兩個變數要放哪裡呢?

如果是過去的網頁Script,可能放在<script>底下,然後透過dom的操作與事件偵測,來處理這些資料。

不過AngularJS本質上是遵循MVC 框架,HTML屬於view的層面,資料不應該放在這裡。而MVC架構中,用來處理Model和View的中介,是透過Controller來進行,因此,我們可以先把資料放進Controller中。

我們來取一個名為controllers.js,放在js這個資料夾中。

 <script type="text/javascript" src="http://code.angularjs.org/angular-1.0.1.min.js"></script>
 <script type="text/javascript" src="js/controllers.js"></script>

至於Controller要怎麼寫呢?其實相當簡單,一個Controller可以用一個函式來代表, 我們把新增待辦事項的Controller命名為TodoCrtl,開始來把剛剛提到的兩個變數放進去。

function TodoCrtl($scope) {
  $scope.newItem = “”;
  $scope.todoList = [{ label: ”買牛奶” }, { label: ”繳電話費” }];
}

這裡預先放了兩個待辦事項到todoList 陣列中,方便我們等一下看效果。

大家一定覺得很奇怪,為什麼會有一個 $scope 傳入,那是什麼東西呢?。記得我們剛剛提過,AngularJS是一個MVC 的架構,而AngularJS在建立應用程式時,會產生一個物件,用來代表應用程式的Model,而這個Model就是上面Controller注入的 $scope。

透過這種方式,Model可以在Controller中進行處理,另外有什麼異動時,也會反應到view中。
寫好我們的Controller之後,我們要把它和view繫連起來,繫連的方法也很簡單,我們在的地方,加上一個標示controller的指令,寫法如下:

 <body ng-controller="TodoCrtl">

把Controller的function的名稱指定給ng-controller指令,繫連就完成了。

【view::加入清單的迭代器】

todoList裡面我們放了兩個代辦事項,那麼要怎麼把它拿出來放在<li>當中呢?

用過去的思維,大概就是算出 todoList的長度之後,用for迴圈來一一取出。不過AngularJS不是這樣做的。

我們先看解答:

<li ng-repeat="item in todoList">{{item.label}}</li>

我們在<li>元素上加入了AngularJS的迭代器ng-repeat,然後指定用"item in todoList"的語法,從todoList這個陣列清單中,取出一個個的物件,指派給item,然後item.label則是我們上一回已經見過的template語法。

到這裡,快去reload一下你的頁面吧,是不是就像下圖一樣的結果呢。大成功。

【加入新增清單的功能】

雖然不用幾行code,就能看到程式動起來,的確讓人感動,不過目前只是列出靜態的資料,我們還要努力一下,才能讓清單動起來。

要動起來的邏輯如下:

在文字框寫入代辦事項 -> 按下「新增待辦事項」-> 清單出現新的代辦事項

為了讓文字框動起來,我們必須把剛剛準備好的newItem和它作連動。因此我們把原來的input稍作修改:

<input type="text" ng-model="newItem" name="newItem" />

指定了ng-model 給<input>,這樣我們就把view和model作好對應了。

接下來我們要在表單送出時,取得input的資料,再做後續的處理,這時我們可以在form上加上這樣的語法:

<form ng-submit="addItem()">

意思是,我們要在按下「新增待辦事項」,也就是送出表單時,去執行 addItem 這個函式。

想當然而,這個動作必須在 TodoCrtl 中執行,於是我們修改 TodoCrtl 的內容如下:

function TodoCrtl($scope) {
  $scope.newItem = “”;
  $scope.todoList = [{ label: ”買牛奶” }, { label: ”繳電話費” }];
  $scope.addItem = function() {
       if(this.newItem) {
           this.todoList.push({label:this.newItem});
           this.newItem = “”;
       }    
  }
}

我們加上了addItem 這個function,在這個fucntion中,我們先判斷在文字框中是不是真有文字,有的話,我們就把資料加入到todoList中,最後再清空<input>中的文字。

在這裡我們也可以看到AngularJS的特色,雖然我只是清空model中的資料,但是在view那邊,你原來輸入的文字也會被即時清空,這就是資料雙向綁定的威力與魅力。

現在你可以reload一下瀏覽器,相信現在已經可以加入待辦事項了。

Live Demo ::完整的程式碼


邊學AngularJS邊做Todo List (1) - Hello World
邊學AngularJS邊做Todo List (2) - Todo List 動起來
邊學AngularJS邊做Todo List (3) - Todo List 刪項目
邊學AngularJS邊做Todo List (4) - 修改待辦事項
邊學AngularJS邊做Todo List (5) - 為測試作準備
邊學AngularJS邊做Todo List (6) - E2E測試(上)


2 則留言

0
ted99tw
iT邦高手 1 級 ‧ 2012-07-18 09:00:53

趕快偷抄到筆記簿先........讚

0
zbrong
iT邦新手 5 級 ‧ 2013-04-24 17:19:46

作者思路清晰,讲解清楚,是好文章!
希望把系列文章写下去,我代表像我这样的有形粉丝(fans),还有数量巨大的无形粉丝,向作者致以崇高的敬意!!!
在此,我也呼吁所有在这里受到教益的粉丝,都当有形粉丝,哪怕来鼓个掌也好。

我要留言

立即登入留言