前 言
AngularJS是一款為了克服HTML在構建應用上的不足而設計的優秀的前端JS框架。AngularJS有着諸多特性,最為核心的是:MVC、模塊化、自動化雙向數據綁定、語義化標簽、依賴注入等等。
AngularJS 是一個 JavaScript 框架。它是一個以 JavaScript 編寫的庫。它可通過 <script> 標簽添加到 HTML 頁面。
AngularJS 通過 指令 擴展了 HTML,且通過 表達式 綁定數據到 HTML。
AngularJS 是以一個 JavaScript 文件形式發布的,可通過 script 標簽添加到網頁中。
AngularJS最初是由MISKO Hevery和Adam Abrons於2009年開發。現在是由谷歌維護。它的最新版本是1.3.14。
各個AngularJS版本下載:https://github.com/angular/angular.js/releases
1. 走進 AngularJS |
AngularJS是為了克服HTML在構建應用上的不足而設計的。 AngularJS使得開發現代的單一頁面應用程序(SPAs:Single Page Applications)變得更加容易。
- AngularJS 把應用程序數據綁定到 HTML 元素。
- AngularJS 可以克隆和重復 HTML 元素。
- AngularJS 可以隱藏和顯示 HTML 元素。
- AngularJS 可以在 HTML 元素"背后"添加代碼。
- AngularJS 支持輸入驗證。
2. AngularJS 中的指令與表達式 |
AngularJS 通過 指令 擴展了 HTML,且通過 表達式 綁定數據到 HTML。
2.1常用指令
AngularJS 指令是擴展的 HTML屬性,帶有前綴 ng-。
1、ng-app=""聲明AngularJS所管轄的區域。一般寫在body或者html標簽上,原則上一個頁面只能有一個。
<body ng-app=""></body>
2、ng-model 指令把元素值(比如輸入域的值)綁定到應用程序的變量中。
<input type="text" ng-model="name"/>
3、 ng-bind把應用程序變量中的值,輸出到頁面HTML視圖中,可以與表達式{{}}互相替換。
<p ng-bind="5+5+'Angular'"></p>
4、ng-init:初始化AngularJS應用程序中的變量值;
<body ng-app="" ng-init="name='NAME'">
應用程序初始化時,name變量就附有初值。
2.2表達式
AngularJS使用{{}}綁定表達式。用於將表達式的內容輸出到頁面中。
表達式中可以是文字、運算符、變量等,也可以在表達式中進行運算輸出結果。
<p>{{5+5+"Angular"}}</p> //結果為 10Angular
如果AngularJS文件放在頁面下方,在頁面刷新的瞬間會看到{{}}表達式的原樣,所以可以使用ng-bind指令代替表達式。
<p ng-bind="5+5+'Angular'"></p>
3. AngularJS中的MVC與作用域 |
3.1MVC三層架構
1、Model(模型層):應用程序中用於處理數據的部分,(包括將數據保存或者修改到數據庫、變量、文件中)。
在AngularJS中,Model特指的是:應用程序中的各種數據。
2、View(視圖層):用戶可以看到的用戶顯示數據的頁面。
3、Controller(控制器):控制器是連接View和Model的橋梁,負責從View讀取數據,接受用戶的操作輸入;並將數據發送給Model層。
Model層對數據處理完畢后,將結果返回給Controller,Controller再將結果返回給View層顯示。
3.2AngularJS中的模塊化開發和依賴注入
創建一個angular的模塊。即ng-app=""所需要綁定的部分。需要接受兩個參數:
①模塊名稱。即ng-app雙引號中需要綁定的名字。
<body ng-app="myapp">
②數組。表示需要注入的模塊名稱,不需要注入其他模塊可用空數組代替。
var app=angular.module("myapp",[]);
>>>Angular將常用的功能封裝到Angular.js,創建主模塊時直接可以使用,無需注入。
>>> 而一些應用較少的功能,需要導入對應的JS文件,並且在[]中注入進這個模塊,才能夠使用。
這就是AngularJS中的【模塊化開發】與【依賴注入】!
在AngularJS的模塊上,創建一個控制器,需要傳入兩個參數:
①控制器名稱:即ng-controller需要綁定的名稱。
<div ng-controller="myCtrl">
②控制器的構造函數,構造函數可以傳入多個參數。
>>>如果要在函數中要使用系統的內置對象,則必須通過函數的參數傳入,否則不能使用。
>>>AngularJS中的內置對象,都用$ 開頭,例如$scope,$rootScope
3.3AngularJS中的作用域
① $scope局部作用域,聲明在$scope上的屬性和方法。只能在當前controller使用;
② $rootScope 根作用域。聲明在$rootScope上的屬性和方法,可以在整個ng-app所包含的范圍使用。
>>>如果沒有使用$scope聲明變量,而是直接使用ng-model在HTML標簽中綁定的數據的作用域為:
1、如果 ng-model寫在某個controller中,則這個變量會默認綁定到當前的controller的$scope上。
2、如果ng-model沒有寫在任何一個controller中,則這個變量會默認綁定到$rootScope 上。
>>>AngularJS中的父子作用域
1、AngularJS中,子作用域只能訪問父作用域中的變量,而不能修改父作用域的變量。
2、為了解決上述問題,可以將父作用域中的變量聲明為引用數據類型,例如對象等。
這樣可以在子作用域中,直接修改對象的屬性,而不需要修改對象本身保存的地址。
<body ng-app="myApp"> <input type="text" ng-model="age" placeholder="age" /> <div ng-controller="myCtrl"> <input type="text" ng-model="name" placeholder="name" /> <div ng-bind="name+'-----myCtrl的name'"></div> <div ng-bind="age+'-----myCtrl的age'"></div> </div> <div ng-controller="myCtrl1"> <div ng-bind="name+ '----myCtrl1的name'"></div> <div ng-bind="age+'-----myCtrl1的age'"></div> <input type="text" ng-model="test" /> <input type="text" ng-model="obj.test" /> <mark ng-bind="test+'myCtrl1-test'"></mark> <mark ng-bind="obj.test+'myCtrl1-obj.test'"></mark> </div> <mark ng-bind="test+'全局-test'"></mark> <mark ng-bind="obj.test+'全局-obj.test'"></mark> <div ng-bind="name + '----全局的name'"></div> <div ng-bind="age+'-----全局的age'"></div> </body>
<script type="text/javascript"> var app = angular.module("myApp",[]); app.controller("myCtrl",function($scope,$rootScope){ $scope.name = "zhangsan"; $rootScope.age = "14"; }); app.controller("myCtrl1",function($rootScope){ $rootScope.test = "aaa"; $rootScope.obj = { test:'bbb' } }); </script>
4.AngularJS 中的過濾器 |
過濾器可以使用一個管道字符(|)添加到表達式和指令中。
>>> 系統內置的過濾器
currency 將數字格式化為貨幣格式
filter 從數組項中選擇一個子集
lowercase 格式化字符串為小寫
orderBy 根據某個表達式排列數組
uppercase 格式化字符串為大寫
angular.module("app",[]) .controller("ctrl",function($scope){ $scope.classes=[ {name:"張三",age:12,score:78}, {name:"李四",age:12,score:66}, {name:"王二麻子",age:12,score:98}, {name:"趙六",age:12,score:54}, {name:"李二狗",age:12,score:75}, ] }) /* * 自定義過濾器 */ .filter("showHello",function(){ return function(text){ return "Hello AngularJS"; } }) .filter("reverse",function(){ return function(text){ return text.split("").reverse().join(""); } }) /* * 自定義過濾器,同時需要傳遞過濾參數 * 調用過濾器示例:<p>{{12345678901| hideTel:4}}</p> * 傳入的參數4,將被過濾函數的num形參所接受 */ .filter("hideTel",function(){ return function(text,num){ num=num>0&&num<11?num:3; text=text+""; var newText=text.substring(0,11-num) +text.substring(11-num,11).replace(/\d/g,"*"); return newText; } }) /* * 自定義過濾器,實現根據姓名篩選數據的功能。 * >>> 調用示例: * 請輸入姓名:<input type="text" ng-model="name"/> * <tr ng-repeat="item in classes | filterByName:name"> */ .filter("filterByName",function(){ return function(items,search){ if(!search) return items; var arr=[]; for (var i=0;i<items.length;i++) { var index=items[i].name.indexOf(search); if (index>-1) { arr.push(items[i]); } } return arr; } })
5.AngularJS中的服務 |
5.1服務Service
1、內置服務:
>>>要使用服務,必須要把服務名通過controller的構造函數的參數注入進來!!!
>>>系統內置的服務,統一使用$開頭,服務中的屬性和方法統一使用$$開頭!!!自定義服務時,需注意與系統服務的寫法區分開;
$location:返回當前頁面的URL地址信息,是一個對象;
var app = angular.module('myApp', []); app.controller('customersCtrl', function($scope, $location) { $scope.myUrl = $location.absUrl(); });
$http:向服務器發送請求,類似於JQuery中的Ajax;
var app = angular.module('myApp', []); app.controller('myCtrl', function($scope, $http) { $http.get("welcome.htm").then(function (response) { $scope.myWelcome = response.data; }); });
$timeout:相當於setTimeout()
var app = angular.module('myApp', []); app.controller('myCtrl', function($scope, $timeout) { $scope.myHeader = "Hello World!"; $timeout(function () { $scope.myHeader = "How are you today?"; }, 2000); });
$interval:相當於setInterval()
var app = angular.module('myApp', []); app.controller('myCtrl', function($scope, $interval) { $scope.theTime = new Date().toLocaleTimeString(); $interval(function () { $scope.theTime = new Date().toLocaleTimeString(); }, 1000); });
2、自定義服務
接收兩個參數:
第一個參數是服務名:
第二個參數是自定義服務的構造函數。 我們自定義的服務,本質是一個對象。
對象的屬性 ,可以在構造函數中,使用this.屬性 表示;
對象的方法 ,可以在構造函數中,使用this.方法 表示;
.service("hexafy",function () { this.gongneng="將十進制數轉化為16進制"; this.func=function (num) { return num.toString(16); } })
使用過濾器實現同樣功能:
.filter("filter1",function(){ return function (num) { return num.toString(16); } })
在過濾器中調用服務!!!
也必須在聲明過濾器的外層構造函數中,注入服務名稱!!!
.filter("filter2",function(hexafy,$location){ return function (num) { return hexafy.func(num); } })
5.2服務Factory
angular.module("app",[]) .controller("ctrl",function ($scope,hexafy) { $scope.gongneng=hexafy.gongneng; $scope.num1=hexafy.func(10); }) .factory("hexafy",function () { var obj={ gongneng:"將十進制數轉化為16進制", func:function (num) { return num.toString(16); } } return obj; })
5.3provider
1、在AngularJs中,service服務 fantory服務都是基於provider服務實現的
2、在定義provider時,可以使用this.$get方法,接受一個函數,函數里面采用與factory完全相同的寫法
.provider("hexafy",function(){ this.$get=function(){ var obj={ gongneng:"將十進制數轉化為16進制", func:function(num){ return num.toString(16); } } return obj; } })
3、在三種服務中,provider服務是唯一可以寫進config配置階段的服務。
所以說,如果服務需要在配置階段,也就是在聲明controller之前執行的話,則可以使用provider,否則一般使用service或者factory。
angular.module("app",[]) /*.config()表示配置階段,在聲明controller之前執行。可以用於聲明一些在controller中 * 需要使用的全局變量、方法、服務等 */ .config(function($provide){ // 在配置階段聲明provider服務,需要在config中注入系統對象$provide $provide.provider("hexafy",function(){ this.$get=function(){ var obj={ gongneng:"444" } return obj; } }); }) .controller("ctrl",function($scope,hexafy){ $scope.gongneng=hexafy.gongneng; })
6. AngularJS 中的select與表格 |
(一)使用數組作為數據源
1、item表示數組中的每一項
2、循環出的option中,value的值,默認為item
3、option顯示出的內容(<option></option>標簽中的文字)是由item.site for決定的!
<select ng-model="site" ng-options="item.site for item in sites" >
這種寫法,默認生成的option效果如下:
<option value="{site : "Google", url : "http://www.google.com"}">Google</option>
<pre>{{site}}</pre>
(二)以對象作為數據源
1、(key,value)第一項表示對象的鍵,第二項表示對象的值;
2、option的value,永遠都是對象的值!
3、option顯示出的內容(<option></option>標簽中的文字)是由...for決定的!也就是說,for前面是什么,option標簽中就是什么。
<select ng-model="site3" ng-options="key for (key,value) in sitess"> <!-- <option value="value">key/value(取決for前面的內容)</option> --> </select>
ng-options 和 ng-repeat
1、ng-options使用時,是將指令添加在select上;
ng-repeat使用時,是將指令添加在option上。
2、ng-options使用時,必須同步給select標簽綁定ng-model;
ng-repeat使用時,不一定需要綁定ng-model;
3、ng-options使用時,我們只需要關心for前面的部分,即option標簽中顯示的文字;而option的value會自動分配,不由我們決定。
(使用數組作為數據源時,value就是數組的每一項;使用對象作為數據源時,value永遠都是對象的值)
ng-repeat使用時,除了要指定option標簽中顯示的文字,
還需要手動指定value中的內容,如果沒有指定,則默認沒有value;
<tr ng-repeat="item in options"> <!-- ng-repeat遍歷是,$index 表示當前的行索引! --> <td>{{$index + 1}}</td> <td>{{item}}</td> </tr>
7.AngularJS中的DOM與事件 |
1、ng-disabled="true/false";
傳入true表示禁用,傳入false表示可用
<button ng-disabled="!myCheck">按鈕</button> <label> <input type="checkbox" ng-model="myCheck" />是否同意! </label> <p>{{myCheck}}</p>
2、ng-show 是否顯示
傳入true表示顯示,傳入false表示隱藏
<label> <input type="checkbox" ng-model="myShow" />是否顯示! </label> <p ng-show="myShow">我顯示出來啦!!!</p> <hr />
3、ng-hide 是否隱藏
<label> <input type="checkbox" ng-model="myHide" />是否隱藏! </label> <p ng-hide="myHide">我顯示出來啦!!!</p>
4、ng-if: 是否移除元素
當傳入true顯示,傳入false時移除。
效果與ng-show相同,但是ng-show和ng-hide只是隱藏元素,而ng-if是將元素從DOM中直接移除!
<label> <input type="checkbox" ng-model="myIf" />是否移除! </label> <p ng-if="!myIf">移除!!!</p>
5、ng-bind-html : 相當於 innerHTML
而ng-bind 相當於 innerText
注意:要使用ng-bind-html,必須導入angular-sanitize.js文件進行安全驗證。
同時需要在聲明模塊的時候,在數組中注入安全驗證模塊'ngSantize'
<div ng-bing-html="html"></div>
6、ng-checked 設置復選框或單選框的選中狀態。
傳入true設置當前復選框被選中。
<input type="checkbox" ng-model="all" /> Check all<br /><br /> <input type="checkbox" ng-checked="all" /> 123<br /> <input type="checkbox" ng-checked="all" /> 456<br /> <input type="checkbox" ng-checked="all" /> 789<br />
7、ng-class:用於設置給元素添加class類。
可選值有以下幾種情況:
① 可以是字符串。表示直接給元素添加對應的class。多個class之間,用空格分隔。
② 可以是對象。對象的鍵表示class名字,對象的值為true或false,當值為true時表示添加對應的class。
③ 可以是數組,數組中的值可以是字符串或對象,判斷規則同上。
<div ng-class="'div div2'">這是一個div</div> <label> <input type="checkbox" ng-model="myClass" />給div添加樣式? </label> <div ng-class="{'div':myClass,'div1':!myClass}">這是一個div</div> <div ng-class="[{'div':myClass,'div1':!myClass},'div3']">這是一個div</div>
8、ng-switch 根據變量的值,選擇不同的ng-switch-when來顯示,當沒有合適的選項時,顯示ng-switch-default
8、AngularJS中的表單和輸入驗證 |
1、表單中,常用的驗證操作:
$dirty 表單有填寫記錄
$valid 字段內容合法的
$invalid 字段內容是非法的
$pristine 表單沒有填寫記錄
$error 表單驗證不通過的錯誤信息
2、驗證時,必須給form和input,設置name屬性。
給form和input設置name后,會自動將表單信息綁定到$scope作用域中。
所以可以直接使用formName.inputName.$驗證操作 得到驗證結果。
例如:
formName.inputName.$dirty = "true"; 表示表單被填寫過!
formName.inputName.$invalid = "true"; 表示表單輸入內容不合法!
formName.inputName.$error.required = "true"; 表示設置了必填,但是沒有輸入!
注意:
$error支持的驗證:required/minlength/maxlength/partten/eamil/num/date/rul等
3、為了避免AngularJS的驗證與HTML5的表單驗證沖突!!比如說 type="email" required等,H5也會進行驗證,那么可以給form添加"novalidate"屬性,禁用HTML5的驗證功能。
<div class="container" style="width: 500px;margin: 50px auto;padding: 0px;"> <div class="panel panel-primary"> <div class="panel-heading"> <div class="panel-title text-center"> 用戶注冊 </div> </div> <div class="panel-body"> <form class="form-horizontal" name="form" novalidate> <div class="row"> <div class="col-xs-3">用戶名</div> <div class="col-xs-9"> <input type="text"class="form-control"name="name" ng-model="user.name" ng-minlength="6" ng-maxlength="12"/> <p style="margin: 0px; color: red;" ng-show="form.name.$invalid && form.name.$dirty"> <span ng-show="form.name.$error.required">用戶名必須填寫</span> <span ng-show="form.name.$error.minlength">用戶名長度最小為6位</span> <span ng-show="form.name.$error.maxlength">用戶名長度最大為16位</span> </p> </div> </div> <div class="row"> <div class="col-xs-3">郵箱:</div> <div class="col-xs-9"> <input type="email" class="form-control" name="email" ng-model="user.email" required/> <p style="margin: 0px;color: red;" ng-show="form.email.$invalid && form.email.$dirty"> <span ng-show="form.email.$error.required">郵箱必須填寫</span> <span ng-show="form.email.$error.email">郵箱不合法</span> </p> </div> </div> <div class="row"> <div class="col-xs-3" >密碼:</div> <div class="col-xs-9"> <input type="password"class="form-control"name="pwd" ng-model="user.pwd" pattern="^\w{6,18}$" required/> <p style="margin: 0px; color: red;" ng-show="form.pwd.$invalid && form.pwd.$dirty"> <span ng-show="form.pwd.$error.pattern">密碼只能由6-18位的字母、數字、下划線</span> </p> </div> </div> <div class="row"> <div class="col-xs-3" >確認密碼:</div> <div class="col-xs-9"> <input type="password"class="form-control" name="repwd" ng-model="user.repwd" required/> <p style="margin: 0px; color: red;" ng-show="user.pwd!=user.repwd && form.repwd.$dirty"> 兩次密碼輸入不一致 </p> </div> </div> <div class="row"> <div class="col-xs-5"> <input type="submit" value="注冊" class="btn btn-success" ng-disabled="form.$invalid||user.pwd!=user.repwd"/> </div> <div class="col-xs-5"> <input type="reset" value="重置" class="btn btn-warning"/> </div> </div> </form> </div> </div> </div>
9.AngularJS中的動畫 |
在AngularJS中使用動畫:
1、導入angular-animate.js
2、如果頁面中沒有自定義的app模塊,則可以直接綁定系統模塊ng-app="ngAnimate"
如果頁面中有自定義的app模塊,則可以在自定義模塊的數組中,注入ngAnimate。
angular.module
3、當使用ng-show、ng-hide顯示或者隱藏元素的時候,系統會自動添加或者移除,ng-hide這個class類。
4、當使用ng-if/ng-switch/ng-repeat等其他指令,需要分別設置顯示后和隱藏后的兩種class樣式;
顯示后的class: .ng-enter-active,.ng-leave{}
顯示后的class: .ng-enter,.ng-leave-active{}