AngularJS 的常用特性(一)

shaopiing發表於2016-05-21

前言:AngularJS 是一款來自 Google 的前端 JS 框架,該框架已經被應用到了 Google 的多款產品中,這款框架最核心特性有:MVC、模組化、自動化雙向資料繫結、語義化標籤、依賴注入等待。而且,AngularJS 框架自身是通過 TDD(測試驅動)的方式開發的,從這個角度來看,AngularJS 是敏捷開發的一次成功實踐。

引一段《AngularJS 深度剖析和最佳實踐》中的話:

Angular的學習曲線大概是這樣的:入門非常容易,中級的時候會發現需要深入理解很多概念,高階的時候需要掌握Angular的工作原理,而想成為專家則很難,需要經過很多工程實踐的磨練。

既然入門比較容易,那就一起入門吧。

1、呼叫 Angular

  為了使用 Angular,所有應用都必須首先做兩件事情:

  • 載入 angular.js 庫
  • 使用 ng-app 指令告訴 Angular 應該管理 DOM 中的哪一部分。

  如果你正在構建一款純 Angular 應用,則把 ng-app 指令寫在 <html> 標籤中,示例如下:

1 <html ng-app>
2     ...
3 </html>

  或者你也可以用 Angular 管理頁面中的一部分,只有放在頁面中的 <div> 之類的元素即可。

1 <html>
2     ...
3     <div ng-app>
4         ...
5     </div>
6     ...
7 </html>

2、模板與資料繫結

  1)資料繫結是 Angular 的特色,即 “所見即所得”,像這樣設定其中的文字:

<p>{{someText}}</p>

  也叫做雙花括號插值語法,因為它可以把新的內容插入到現有的模板中。

  控制器(使用指令 ng-controller)就是你所編寫的類或者型別,它的作用是告訴 Angular 該模型是由哪些物件或者基本資料構成的,只要把這些物件或者基本資料設定到 $scope 物件上即可,$scope 物件會被傳遞給控制器:

1 function TextController($scope) {
2   $scope.someText = someText;  
3 }

  一個簡單的完整的例子:

 1 <html ng-app>
 2     <body ng-controller="TextController">
 3         <p>{{someText}}</p>
 4         <script src="../src/angular.js"></script>
 5         <script>
 6             function TextController($scope) {
 7                 $scope.someText = 'You have started your journey.';
 8             }
 9         </script>
10     </body>
11 </html>

  載入到瀏覽器中,你會看到:

You have started your journey.

  但是大多數應用,還是需要建立模型物件來容納資料,而且並不建議在全域性作用域建立 TextController,建議是定義成模組的一部分

 1 <html ng-app="myApp">
 2     <body ng-controller="TextController">
 3         <p>{{someText}}</p>
 4         <script src="../src/angular.js"></script>
 5         <script>
 6             var myAppModule = angular.module('myApp', []);
 7 
 8             myAppModule.controller('TextController', function ($scope) {
 9                 var someText = {};
10                 someText.message = 'You have started your journey.';
11                 $scope.someText = someText;
12             });
13         </script>
14     </body>
15 </html>

  記住:把東西從全域性名稱空間中隔離開是一件非常好的事情,模組機制起這個作用。

  2)使用 ng-bind 指令,可以在 UI 中的任何地方顯示並重新整理文字,有兩種等價形式:

  一種是花括號形式:

<p>{{greeting}}</p>

  一種是使用基於屬性的指令:

<p ng-bind="greeting"></p>

  花括號插值語法的目的是為了閱讀自然,而且需要輸入的內容更少,但是在頁面載入過程中,Angular 會使用資料替換這些花括號,未被渲染好的模板可能會被使用者看到。

  造成這種現象的原因是,瀏覽器需要首先載入 HTML 頁面,渲染它,然後 Angular 才有機會把它解釋成你期望看到的內容。

  其實,載入 HTML 頁面一般只發生在首頁,所以對於 index.html 頁面中的資料繫結操作,建議使用 ng-bind,其他頁面可以使用花括號,而且花括號更快一點。

  利用 Chrome 瀏覽器的一個針對於 Angular 的擴充套件(AngularJS Batarang(Stable))可以直觀的看到兩者消耗時間的差別:

  

  3)表單輸入

  在 Angular 中使用表單元素非常方便,使用指令 ng-model 屬性把元素繫結到你的模型屬性上。

1 <form ng-controller="SomeController">
2     <input type="checkbox" ng-model="youCheckedIt">
3 </form>

  對於輸入元素來說,你可以使用 ng-change 屬性來指定一個控制器方法,一旦使用者修改了輸入值,這個方法就會被呼叫。下面做一個簡單的計算,幫助消費者計算一下需要付多少錢:

1 <form ng-controller="StartUpController">
2     Starting : <input ng-change="computeNeeded()" ng-model="funding.startingEstimate">
3     Recommendation: {{funding.needed}}
4 </form>

  把輸入文字框的值設定為使用者估價的 10 倍即可,同時,預設值為 0:

1     function StartUpController($scope) {
2         $scope.funding = { startingEstimate : 0};
3 
4         $scope.computeNeeded = function () {
5             $scope.funding.needed = $scope.funding.startingEstimate * 10;
6         }
7     }

  但是為了能夠正確地重新整理輸入框,而不管它是通過何種途徑進行重新整理的,需要使用 $scope 中的 $watch() 函式:

1 function StartUpController($scope) {
2   $scope.funding = { startingEstimate : 0};
3 
4    var computeNeeded = function () {
5      $scope.funding.needed = $scope.funding.startingEstimate * 10;
6    };
7         
8    $scope.$watch('funding.startingEstimate', computeNeeded);
9 }

  請注意,需要監視的表示式位於引號中,這個字串會被當作 Angular 表示式來操作。這時我們可以使用一個簡單的模板:

1 <form ng-controller="StartUpController">
2     Starting : <input ng-model="funding.startingEstimate">
3     Recommendation: {{funding.needed}}
4 </form>

  4)淺談非入侵式 JavaScript

  對於大多數內聯的時間監聽器來說,Angular 有一種等價的形式 ng-eventhandler = "expression",這裡的 eventhandler 可以被替換成 click、mousedown、change等。最重要的是,Angular將會幫你遮蔽瀏覽器之間的差異性

  而且不會在全域性名稱空間中進行操作,你所指定的表示式只能訪問元素控制器作用域範圍內的函式和資料

  第二點舉個例子就是,不同的 Controller,可以定義相同名字的資料模型,你會建立一個導航欄和一個內容區域,當你在導航欄中選擇不同的選單項時,內容區域會發生相應的改變。

 1 <div class="navbar" ng-controller="NavController">
 2     ...
 3     <li class="menu-item" ng-click="doSomething()">Something</li>
 4     ...
 5 </div>
 6 
 7 <div class="contentArea" ng-controller="ContentAreaController">
 8     ...
 9     <div ng-click="doSomething()">...</div>
10     ...
11 </div>

  當使用者點選的時候,導航欄中的兩個 <li> 和內容區域中的 <div> 都會呼叫 doSomething() 的函式,你可以在控制器程式碼中寫好這些呼叫所引起的函式,實際上這兩個函式可以是同一個,也可以不是同一個。

1 function NavController($scope) {
2     $scope.doSomething = doA;
3 }
4 function ContentAreaController($scope) {
5     $scope.doSomething = doB;
6 }

  請注意,到目前為止,我們所編寫的所有控制器中,都沒有在任何地方引用 DOM 或者 DOM 操作,所有定位元素和處理事件的工作都是在 Angular 內部完成的。

  所以,你可以開心地使用 Angular 的宣告式事件處理器,同時又能保持簡單性和可讀性,沒有必要為違反最佳實踐而感到內疚。

  特別鳴謝:《用 AngularJS 開發下一代 Web 應用》

相關文章