一、AngularJS簡介
1.1 什么是AngularJS
(1)一款非常優秀的前端JS框架,可以方便實現MVC/MVVM模式
(2)由Misko Hevery 等人創建,2009年被Google所收購,用於其多款產品
(3)Google目前有一個全職的開發團隊繼續開發和維護這個庫
(4)有了這一類框架就可以輕松構建SPA單頁應用程序
(5)通過指令擴展了HTML,通過表達式綁定數據到HTML,輕松實現雙向綁定
單頁Web應用(single page web application,SPA),就是只有一張Web頁面的應用,是加載單個HTML 頁面並在用戶與應用程序交互時動態更新該頁面的Web應用程序。
- 首先,最大的好處是用戶體驗,對於內容的改動不需要加載整個頁面。這樣做好處頗多,因為數據層和UI的分離,可以重新編寫一個原生的移動設備應用程序而不用(對原有數據服務部分)大動干戈。
- 單頁面Web應用層程序最根本的優點是高效。它對服務器壓力很小,消耗更少的帶寬,能夠與面向服務的架構更好地結合。
1.2 AngularJS有哪些特性
(1)MVC,MVVM
(2)模塊化
(3)自動化雙向數據綁定
(4)指令系統(非侵入式API)
二、第一個AngularJS程序
2.1 下載AngularJS
方式一:NPM(npm install angular)
方式二:下載angular.js包(https://github.com/angular/angular.js/releases)
方式三:使用CDN上的angular.js(http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js)
這里我們使用方式三,CDN方式。
2.2 體驗雙向數據綁定
新建一個HTML頁,輸入一下內容:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Hello Angular</title> <meta charset="utf-8" /> <style type="text/css"> #main { text-align: center; } </style> </head> <body> <div id="main" ng-app ng-init="name='World'"> <p>Your name:<input type="text" ng-model="name" /></p> <p>Hello {{name}}!</p> </div> <script type="text/javascript" src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> </body> </html>
(1)ng-app指令標記當前元素將被Angular進行管理。
(2)文本輸入指令<input type="text" ng-model="name" />綁定到一個叫name的模型變量。
(3)雙大括號標記將name模型變量添加到問候語文本。
運行該HTML頁,可以發現,當我們在textbox中輸入什么,問候語中都會及時進行綁定:
三、理解AngularJS中的指令
3.1 以前我們是這樣寫的
假如我們有一個頁面需要計算用戶填寫的數字*2的結果是多少,我們可能會有一個HTML界面和JavaScript代碼如下:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Use JavaScript</title> <meta charset="utf-8" /> <style type="text/css"> #main { text-align:center; } </style> </head> <body> <div id="main"> <input type="text" id="value" /> <input type="button" value="*2" id="btn" /> </div> <script type="text/javascript"> (function(window) { // 利用querySelector找到界面上的按鈕dom元素並增加事件監視器 window.document.querySelector('#btn').addEventListener('click', function() { // 獲取DOM元素 var input = window.document.querySelector('#value'); // 獲取填寫數值 var value = input.value; // 執行業務操作 value = value - 0; value = value * 2; // 設置顯示結果 input.value = value; }); })(window); </script> </body> </html>
運行結果如下圖所示:
3.2 現在我們可以這樣寫
<!DOCTYPE html> <!-- ng-app與ng-controller不能位於同一級目錄 --> <html ng-app="myApp"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Use AngularJS</title> <meta charset="utf-8" /> <style type="text/css"> #main { text-align: center; } </style> </head> <body ng-controller="DemoController"> <div id="main"> <input type="text" id="value" ng-model="value" /> <input type="button" value="*2" id="btn" ng-click="doCalc()" /> </div> <script type="text/javascript" src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> <script type="text/javascript"> (function (window) { // 1.模塊 var myApp = window.angular.module('myApp', []); // 2.控制器 myApp.controller('DemoController', function ($scope) { $scope.value = 10; $scope.doCalc = function () { $scope.value = $scope.value * 2; }; }); })(window); </script> </body> </html>
(1)在AngularJS中,ng-app、ng-controller等都是指令,通過指令擴展HTML,通過表達式綁定數據到HTML。
(2)網頁加載完成后,angular.js這個腳本就會自動執行,執行過程主要是去界面上找到ng-app指令。
(3)ng-app指令的作用在於聲明當前DOM被AngularJS這個庫中定義的一個模塊所托管,而ng-model指令則用於綁定模型變量,ng-click綁定控制器中聲明的事件。可以看出,controller中的邏輯是一個典型的閉包實現。
(4)window.angular.module('myApp', []) 表示通過angular注冊一個module模塊,這個模塊名是myApp,第二個參數傳入這個模塊所依賴的其他模塊,沒有需要其他模塊的話就為空。
(5)myApp.controller('DemoController', function ($scope) {}) 表示為myApp創建一個controller控制器,這個控制器名是DemoController,第二個參數傳入這個控制器的控制邏輯。
運行結果如下圖所示,和之前的效果一樣:
三、開發一個任務清單程序
3.1 需求說明
假設我們要做一個任務清單程序,它可以記錄我們要做的所有任務信息,並且我們可以隨時標記任務為已完成,而且隨時增加新的任務到任務列表中。在AngularJS的各種示例程序中,TodoMVC算是一個比較出名的項目,如下圖所示:
這里我們的目標就是仿照TodoMVC,借助AngularJS實現一個簡易版的TodoList頁面。
3.2 開發實現
(1)借助Bootstrap實現界面,引入AngularJS綁定模型變量
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>任務列表 - By AngularJS</title> <meta charset="utf-8" /> <link href="assets/css/bootstrap.min.css" rel="stylesheet" /> <style type="text/css"> body.container { max-width: 600px; } .checkbox { margin-bottom: 0px; margin-right: 20px; } .done { color: #ccc; } .done > .checkbox > label > span { text-decoration: line-through; } </style> </head> <body class="container" ng-app="TodoApp"> <header> <h1 class="display-1">我的任務列表</h1> <hr /> </header> <section ng-controller="MainController"> <form class="input-group input-group-lg"> <input type="text" class="form-control" ng-model="textValue" /> <span class="input-group-btn"> <button class="btn btn-secondary" ng-click="addTask()">添加</button> </span> </form> <ul class="list-group m-y-2"> <li class="list-group-item" ng-repeat="item in todoList" ng-class="{'done':item.done}"> <button type="button" class="close" aria-label="Close" ng-click="deleteTask(item)"> <span aria-hidden="true">×</span> <span class="sr-only">Close</span> </button> <div class="checkbox"> <label> <input type="checkbox" ng-model="item.done" /> <span>{{item.textValue}}</span> </label> </div> </li> </ul> <p>總共<strong>{{todoList.length}}</strong>個任務,已完成<strong>{{updateDone()}}</strong>個</p> </section> <script type="text/javascript" src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script> <script type="text/javascript" src="assets/js/app.js"></script> </body> </html>
(2)完善app.js,在其中寫入angular關鍵代碼
(function (window) { // 01.注冊一個應用程序的主模塊(module方法如果之傳入一個參數就不是創建一個新模塊) window.angular.module("TodoApp", []); //02.為主模塊注冊控制器(直接取得一個已存在的模塊,不會存在全局污染) window.angular.module("TodoApp").controller("MainController", ["$scope", function ($scope) { // part01.定義屬性 $scope.textValue = ""; // 文本框中的值 $scope.todoList = [ { textValue: "學習AngularJS基礎", done: false }, { textValue: "學習BootStrap基礎", done: false }, { textValue: "學習ASP.Net MVC基礎", done: false }, { textValue: "學習ASP.Net WebApi基礎", done: false } ]; // 任務列表,這里是寫死的,實際中是通過AJAX拿到的 // part02.定義行為 // 增加任務行為 $scope.addTask = function () { var textValue = $scope.textValue.trim(); if (textValue) { // 加入任務列表 $scope.todoList.push({ textValue: textValue, done: false }); // 清空文本框值 $scope.textValue = ""; } } // 刪除任務行為 $scope.deleteTask = function (task) { var index = $scope.todoList.indexOf(task); $scope.todoList.splice(index, 1); // 等價於remove方法 } // 更新已完成任務數行為 $scope.updateDone = function () { var temp = $scope.todoList.filter(function (item) { // 返回true表示當前item滿足條件 return item.done; }); return temp.length; } }]); })(window);
可以看出,在控制器中屬性和行為分開定義,職責分明。
(3)運行TodoList頁面,結果如下圖所示:
附件下載