2014年7月2日 星期三

AngularJS 教學 - 事件處理

本篇說明一下事件處理的方式以及種類,最後在說明 AngularJS 對於 Event 的定義

在 MVC 中的視圖(View),除了需要將資料做呈現之外,另外一個工作就是註冊事件了,

只要是寫過 Javascript 或是 jQuery 或是任何一種 Widget 的套件,都一定會處理這些事件的

例如 Javascript 的 onClick 事件,我們會將 onClick 屬性寫在 button 元素上,並指定一個

callback function 來執行按下按鈕時的處理邏輯,在AngularJS 教學 - Controller and View中有提到

AngularJS 在撰寫這一類的事件處理時,會由 View 負責註冊事件,由 Controller 負責處理

事件的後續邏輯。

以下是從官方網站節錄出來的事件列表,大致上看看就好了
ng-click ng-dblclick ng-change ng-blur ng-focus
ng-keydown ng-keypress ng-keyup ng-submit ng-mousedown
ng-mouseenter ng-mouseleave ng-mousemove ng-mouseover ng-mouseup
ng-copy ng-cut ng-paste


接下來用一個簡單的 click 事件來介紹 AngularJS 的 event handle

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="demoApp">
     <head>
         <title>Examples</title>
         <script type="text/javascript" src="js/angular.min.js"></script>
         <script>
              var demoApp = angular.module("demoApp", []);
              demoApp.controller("demoCtrl", function($scope){
                  $scope.count = 0;
                 $scope.handleClick2 = function(){
                    $scope.count++;
                 };

                 $scope.handleClick3 = function(e){
                    console.log(e.type);
                    $scope.count++;
                 };
             });
         </script>
     </head>
     <body>
         <div ng-controller="demoCtrl">
              Count:{{count}}<br/>
              <button ng-click="count = count +1">Button1</button><br/>
              <button ng-click="handleClick2()">Button2</button><br/>
              <button ng-click="handleClick3($event)">Button3</button><br/>
         </div>
     </body>

</html>

可以看到上面的範例在 View 中定義了三個 button,三個 button 都有註冊 ng-click 屬性

三個 button 的 ng-click 屬性值的處理都有些許不同

第一個 button 是直接在 ng-click 內寫上 Expression (通常稱做 inline expression)

第二個 button 則是給定了一個 Controller 的 function "handleClick2" 做為事件觸發的 callback function

第三個跟第二個一樣,只是多傳入了一個 $event 的物件,並寫在 callback function 中印出

$event 的 type 屬性值,以本例來說會是 "click"。


最後來說明一下 Event 在 AngularJS 內扮演的角色吧

我先舉一個例子,如果要做到一個網頁中的一個下拉選單  在選擇某一個項目時

下方的 input text 就要呈現出被選擇的項目

在以往的 jQuery 或是 Javascript 或是其它套件,想當然都會寫一個 onChange 的 Event 在 select 的元素上

並定義一個 callback 函式  負責取出被選擇項目的值然後再辛苦的把這個值塞給下面的 input text

在 AngularJS 內你當然也可以這樣做,但有一個更好的方式就是用 ng-model

也就是利用 AngularJS 的 Two-Way Binding 的方式來達成我剛剛描述的情況

可以先參考之前寫的 AngularJS 教學 - Data Binding

以下我簡單寫了一個範例來 demo Two-Way Binding 的方式來做到類似 event handle 的結果

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="demoApp">
     <head>
         <title>Examples</title>
         <script type="text/javascript" src="js/angular.min.js"></script>
         <script>
              var demoApp = angular.module("demoApp", []);
              demoApp.controller("demoCtrl", function($scope){
                  $scope.selectedItem1 = "A";
             });
         </script>
     </head>
     <body>
         <div ng-controller="demoCtrl">
              <p>Using ng-model</p>
              <select ng-model="selectedItem1">
                  <option value="A">A</option>
                  <option value="B">B</option>
                  <option value="C">C</option>
              </select>
              <input type="text" ng-model="selectedItem1" disabled />
         </div>
     </body>

</html>

我在 select 和 input 元素都指定了 ng-model="selectedItem1"

表示了這兩個 View 上的元素都在同一個 Controller 下參考了同一個 Model (selectedItem1)

由於 ng-model 本身就是一個建立 Two-Way Binding 的方式之一

因此當上面的下拉選單變換時,Model (selectedItem1) 的值也會跟著變換

所以所有參考 Model  (selectedItem1) 的視圖都會變化。

因此在你要寫事件處理時,不仿想想看你的需求是不是一個 Two-Way Binding 就可以解決了呢

畢竟這也沒有一個最標準的答案,看你的需求,見仁見智了

沒有留言:

張貼留言