AngularJS
AngularJS基礎
AngularJS簡介
AngularJS是一個用於構建單頁面應用的前端JS框架,在前端踐行了MVC設計模式。
AngularJS是一個前端JS框架,或者叫做一個JS庫,可以通過script標籤的形式引用到HTML頁面上。
AngularJS與Angular2以上爲兩套不同的框架體系
<script src="https://cdn.bootcss.com/angular.js/1.6.3/angular.js"></script>
AngularJS是一些以Misko Hevery爲首的後端程序員開發出來的前端框架,後被谷歌公司收購併廣泛應用於谷歌的各種大小項目。
多頁面應用和單頁面應用
多頁面應用和單頁面應用的頁面結構對比
一個AngularJS簡單應用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第一個AngularJS簡單應用</title>
<script src="https://cdn.bootcss.com/angular.js/1.6.3/angular.js"></script>
</head>
<body>
<!--ng-app聲明Angular的作用範圍-->
<div ng-app>
<!--ng-model來將輸入框裏的內容綁定給變量name-->
<input type="text" ng-model="name">
<div>
<!--字符串模板,用於在頁面上直接顯示變量內容-->
你好,{{name}}<br>
<!--字符串模板中的內容是AngularJS表達式(包含JS表達式)-->
{{1 + 1}}<br>
{{3>2?"3大於2":"3不大於2"}}
</div>
</div>
</body>
</html>
ng-app
ng-app用來聲明當前頁面中angular應用的作用範圍, 可以寫在包括<html>
和<body>
的所有標籤上,這時,這個標籤和其字標籤就都在angular應用的作用範圍之內了。
AngularJS核心特性
AngularJS通過 指令 和 字符串模板 將 數據模型(Model) 和 視圖(View) 中的對應的數據 雙向綁定 。
指令
指令 就是以 ng- 開頭的一些擴展HTML標籤屬性,比如 ng-app 、ng-model 。在標籤上使用指令,就可以讓標籤具有一些AngularJS提供的功能。
字符串模板
字符串模板 就是以被 {{}} 包含的一些 AngularJS表達式 , AngularJS表達式 包括JS表達式和AngularJS專有的特殊表達式。
雙向綁定
當 視圖(View) 上顯示的內容發生變化時,數據模型(Model) 中相應的變量會隨之變化。
當 數據模型(Model) 中的變量發生變化時,視圖(View) 上顯示的內容會隨之變化。
MVC設計模式
MVC設計模式說明
第一個AngularJS正式應用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>第一個AngularJS正式應用</title>
<script src="https://cdn.bootcss.com/angular.js/1.6.3/angular.js"></script>
</head>
<body>
<!--ng-app聲明Angular的作用範圍,如果不想使用默認的AngularJS控制器,就要給ng-app起一個名字-->
<!--ng-controller聲明自定義控制器的作用範圍,必須使用as給控制器起一個別名-->
<div ng-app="myApp" ng-controller="myCtrl as mc">
<!--在當前控制器作用範圍內,可以使用別名訪問控制器的屬性-->
{{mc.name}}
<!--字符串模板也可以應用在標籤的普通屬性中-->
<img src="head.jpg" title="{{mc.imgTip}}">
</div>
<script>
"use strict";
//獲取頁面中的應用,作爲AngularJS的控制區域
var myApp = angular.module("myApp",[]);
//爲APP對象提供一個Controller
//第二個參數,是Controller的構造函數
myApp.controller("myCtrl",function(){
//爲了避免this指向改變造成的問題並且使用起來更加方便,將this轉存
var mc = this;
mc.name = "lins";
mc.imgTip = "這是我的頭像";
});
</script>
</body>
</html>
angular.module
用於創建或者獲取指定的angular應用。
//創建: angular.moudle("ng-app的值,即應用的名字",["配置信息"]);
angular.module("myApp",[]);//注:即使沒有配置信息,也要寫一個空數組
//獲取: angular.moudle("ng-app的值,即應用的名字");
angular.module("myApp");
controller
用於嚮應用添加控制器。
//myApp.controller("控制器名字",構造函數);
myApp.controller("myCtrl",function(){
//爲了避免this指向改變造成的問題並且使用起來更加方便,將this轉存
var mc = this;
mc.屬性名 = 值;
mc.函數名 = function(){
};
});
AngularJS應用程序開發步驟
1、引用AngularJS庫。
2、ng-app、ng-controller。
3、創建應用程序、添加控制器。
4、雙向綁定。
AngularJS初級語法
使用ng-repeat展示數組中的數據
語法:
<!--簡單數組-->
<標籤 ng-repeat="引用 in 數組">{{引用}}</標籤>
<!--對象的數組-->
<標籤 ng-repeat="引用 in 數組">{{引用.屬性}}</標籤>
展示簡單數組
<div ng-app="myApp" ng-controller="myCtrl as mc">
<ul>
<!--ng-repeat會將所在的標籤及其子標籤根據數組元素的個數進行復制-->
<li ng-repeat="i in mc.array">{{i}}</li>
</ul>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.array = [0,1,3,52];
});
</script>
展示對象的數組
<div ng-app="myApp" ng-controller="myCtrl as mc">
<table border="1px">
<tr>
<td>序號</td>
<td>用戶名</td>
<td>年齡</td>
</tr>
<tr ng-repeat="u in mc.users">
<!--$index是ng-repeat語法中的特殊屬性,指當前遍歷的下標,number類型,從0開始-->
<td>{{$index + 1}}</td>
<td>{{u.name}}</td>
<td>{{u.age}}</td>
</tr>
</table>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.users = [
{name:"lins",age:24},
{name:"suns",age:18},
{name:"zhang3",age:18}
];
});
</script>
展示簡單數組時的注意事項
當簡單數組中有兩個 等價 (類似於===,但是NaN等價於NaN)的元素時,需要track by 每次遍歷時唯一的值以進行區別。
<div ng-app="myApp" ng-controller="myCtrl as mc">
<ul>
<!--$index是當前遍歷的下標,可以作爲每次遍歷時唯一的值-->
<li ng-repeat="i in mc.array track by $index">{{i}}</li>
</ul>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.array = [0,1,3,52,3];
});
</script>
ng-repeat中的其他特殊屬性**
在ng-repeat中,除了$index是常用的number型特殊屬性外,還有5種boolean型的特殊變量供我們使用。
特殊屬性 | 爲true條件 |
---|---|
$first | 遍歷時的第一個(即下標爲0) |
$last | 遍歷時的最後一個(即下標爲length-1) |
$odd | 下標爲奇數的(注意下標從0開始,即傳統意義上的偶數) |
$even | 下標爲偶數的(注意下標從0開始,即傳統意義上的奇數) |
$middle | 遍歷時除了第一個和最後一個(0 < 下標 < length - 1) |
根據條件展示
AngularJS可以根據某個表達式的結果決定某部分內容是否顯示。這種特性在許多場景下都有重要應用,常見的是用於在服務器端數據未加載完成時顯示提示信息。
AngularJS用了兩種不同的方式來實現這一特性。
- 根據表達式的結果,決定是否動態創建這個DOM元素: ng-if 和 ng-switch 。
- 根據表達式的結果,決定是否顯示這個標籤: ng-show 和 ng-hide 。
兩種方式比較
- 動態創建DOM的效率比修改標籤顯示方式的效率低很多。
- 動態創建DOM的方式能避免極個別情況下的樣式錯誤或邏輯錯誤。
因此需要根據使用場景來決定採取何種方式。
ng-if
語法:
<!--爲true顯示,爲false不顯示-->
<標籤 ng-if="布爾表達式"></標籤>
例子:
<div ng-app="myApp" ng-controller="myCtrl as mc">
<div ng-if="mc.myVar==1">ng-if 1</div>
<div ng-if="mc.myVar==2">ng-if 2</div>
<div ng-if="mc.myVar==3">ng-if 3</div>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.myVar = 2;
});
</script>
ng-switch
語法:
<標籤 ng-switch="表達式">
<!--根據表達式的結果匹配顯示對應標籤,當都不匹配時,顯示default對應的(如果有)-->
<標籤 ng-switch-when="值1"></標籤>
<標籤 ng-switch-when="值2"></標籤>
<標籤 ng-switch-default></標籤>
</標籤>
例子:
<body>
<div ng-app="myApp" ng-controller="myCtrl as mc">
<div ng-switch="mc.test">
<div ng-switch-when="1">1</div>
<div ng-switch-when="2">2</div>
<div ng-switch-default>默認</div>
</div>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.test = 1;
});
</script>
ng-show
語法:
<!--爲true顯示,爲false不顯示-->
<標籤 ng-show="布爾表達式"></標籤>
例子:
<div ng-app="myApp" ng-controller="myCtrl as mc">
<div ng-show="mc.myVar==1">ng-show 1</div>
<div ng-show="mc.myVar==2">ng-show 2</div>
<div ng-show="mc.myVar==3">ng-show 3</div>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.myVar = 2;
});
</script>
ng-hide**
ng-show的反邏輯,即爲true不顯示,爲false顯示。不常用。
特殊屬性綁定
ng-src和ng-href
ng-src 用於代替圖片的src屬性,用於防止數據加載完畢前的錯誤圖像顯示。
ng-href 用於代替鏈接的href屬性,用於防止數據加載完畢前的錯誤鏈接指向。
<div ng-app="myApp" ng-controller="myCtrl as mc">
<img ng-src="{{mc.image}}">
<a ng-href="{{mc.url}}">鏈接</a>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.image = "head.jpg";
mc.url = "http://www.baidu.com";
});
</script>
ng-class
ng-class 可以使用擴展的AngularJS表達式來更加智能的動態控制標籤樣式。包括單值語法、數組語法和對象語法。
單值語法
<!--直接將屬性的值作爲class-->
<標籤 ng-class="某個屬性"></標籤>
數組語法
<!--將數組中所有的元素的值作爲class,自動使用空格分隔-->
<標籤 ng-class="[屬性1,屬性2]"></標籤>
對象語法
<!--根據布爾表達式動態控制class,當某個屬性值爲true時,相應的屬性名會加入class-->
<標籤 ng-class="{'樣式名稱1':布爾表達式1,'樣式名稱2':布爾表達式2}"></標籤>
綁定表單元素
ng-model 可以雙向綁定表單元素。
普通文本框
<input type="text" ng-model="mc.name">
<input type="password" ng-model="mc.pass">
單選框
<div ng-app="myApp" ng-controller="myCtrl as mc">
<input type="radio" ng-model="mc.r" value="1">1
<input type="radio" ng-model="mc.r" value="2">2
<input type="radio" ng-model="mc.r" value="3">3
<br>
{{mc.r}}
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
//可以進行默認選中,注意必須是字符串的值
mc.r = "2";
});
</script>
多 選框
注意:對於多選框,ng-model只能綁定其checked屬性(true或false。 因此,如果想要進行默認選中,一般需要使用另一個指令 ng-checked ;並且,多個選擇框不要使用同樣的ng-model值,否則會發生聯動。
由於這種特性,故多選框不適合用來做表單提交,多用於結合ng-if或ng-show來做出選中時顯示額外內容的效果。
<div ng-app="myApp" ng-controller="myCtrl as mc">
<input type="checkbox" ng-model="mc.c1" value="a" ng-checked="mc.ca == 1">A
<input type="checkbox" ng-model="mc.c2" value="b" ng-checked="mc.cb == 2">B
<input type="checkbox" ng-model="mc.c3" value="c" ng-checked="mc.cc == 3">C
<br>
mc.c1:{{mc.c1}}<br>
mc.c2:{{mc.c2}}<br>
mc.c3:{{mc.c3}}<br>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.c2 = true;
mc.cb = "2";
});
</script>
下拉列表框
- 當option標籤沒有value屬性時,ng-model和標籤體綁定,取值和默認賦值依據標籤體進行。
- 當option標籤有value屬性時,ng-model和value屬性綁定,取值和默認賦值依據value屬性進行。
<div ng-app="myApp" ng-controller="myCtrl as mc">
<select ng-model="mc.s1">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>{{mc.s1}}</span>
<select ng-model="mc.s2">
<option value="aa">AA</option>
<option value="bb">BB</option>
<option value="cc">CC</option>
</select>
<span>{{mc.s2}}</span>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.s1 = "C";
mc.s2 = "aa";
});
</script>
AngularJS對事件的封裝
綁定到控制器屬性中的函數,除了可以在控制器中直接調用外,更多的應用是作爲事件的處理函數。使用AngularJS封裝的事件(也是一種AngularJS指令),可以直接處理AngularJS管理的各種動態數據。
例子:
<div ng-app="myApp" ng-controller="myCtrl as mc">
<input type="text" ng-model="mc.text">
<button ng-click="mc.btn_click()">加入</button>
<ul>
<li ng-repeat="txt in mc.array">{{txt}}</li>
</ul>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function() {
var mc = this;
mc.array = [];
mc.btn_click = function () {
mc.array.push(mc.text);
mc.text = "";
}
});
</script>
AngularJS事件型指令列表
事件(指令) | 觸發時機 | 觸發元素 |
---|---|---|
ng-click | 鼠標單擊 | 任意標籤 |
ng-dblclick | 鼠標雙擊 | 任意標籤 |
ng-mouseenter | 鼠標移入 | 任意標籤 |
ng-mouseleave | 鼠標移出 | 任意標籤 |
ng-mousemove | 鼠標移動 | 任意標籤 |
ng-change | 表單元素中用戶輸入的數據每次被改變 | 表單元素 |
ng-copy | 在多種情況下觸發,包括複製、選中等 | 表單元素 |
ng-cut | 表單元素中用戶輸入的數據每次被剪切 | 表單元素 |
ng-paste | 表單元素中用戶輸入的數據每次被粘貼 | 表單元素 |
ng-focus | 表單元素每次獲得焦點 | 表單元素 |
ng-blur | 表單元素每次失去焦點 | 表單元素 |
注:ng-change必須配合ng-model使用。
AngularJS中級語法
AngularJS的代碼侵入性比較強,很難兼容於類似於jQuery之類的其他前端框架。故不能使用jQuery來操作AngularJS中管理的數據。
依賴注入簡介
依賴注入(Dependency Injection,簡稱DI)是指一個功能需的一些功能組件(對象、函數等)不是由這個功能本身創建,而是由其他功能創建。前者無需關心這一功能組件的實現。
最簡單的依賴注入的例子就是調用函數時傳參:函數無需關心傳入的參數是如何得來的,只需要聲明這個參數,就可以直接使用。
服務
服務 在AngularJS中是一個函數或一個對象,它可以依賴注入到任何需要使用它的控制器中。
AngularJS提供的服務以$開頭。常用的有 $timeout、$interval 、$scope、$rootScope和$http。
$timeout和$interval
在AngularJS中,不能直接使用setTimeout和setInterval來操作AngularJS中的動態變量。 如果需要類似這樣的功能,需要使用AngularJS的$timeout和$interval服務。
例子:
<div ng-app="myApp" ng-controller="myCtrl as mc">
{{mc.test}}
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function($timeout,$interval){
var mc = this;
mc.test = 1;
var p1 = $timeout(function(){
mc.test ++;
},2000);
var p2 = $interval(function() {
mc.test ++;
},500);
$timeout.cancel(p1);
$interval.cancel(p2);
});
</script>
解決代碼壓縮引發的依賴注入的問題
由於依賴注入是根據聲明自動注入的,因此要求形參的名字必須完全一致。然而js代碼經過壓縮後,會自動變更形參的名字,使得注入失效。AngularJS也針對這種情況提出來一種新的寫法, 當我們使用依賴注入時,務必要採取這種寫法 。
寫一個數組,將被注入的函數爲數組的最後一個元素。將注入的服務寫成形參的同時以字符串的形式作爲數組的前幾個元素, 並且這幾個字符串和形參保持順序一致 。
如上例可以寫成這樣:
<div ng-app="myApp" ng-controller="myCtrl as mc">
{{mc.test}}
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",["$timeout","$interval",function($timeout,$interval){
var mc = this;
mc.test = 1;
var p1 = $timeout(function(){
mc.test ++;
},2000);
var p2 = $interval(function() {
mc.test ++;
},500);
$timeout.cancel(p1);
$interval.cancel(p2);
}]);
</script>
$scope**
$scope是作用域,每個controller都有一個作用域,ng-repeat等一些比較特殊的指令也會創建新的子作用域,ng-model和ng-init也可以直接把一些數據直接綁定到作用域中。 ** 在一些比較大的AngularJS項目中,作用域的關係錯綜複雜,因此不建議大家使用$scope和ng-init。**
例子:
<div ng-app="myApp" ng-controller="myCtrl as mc">
<!--綁定到作用域中的屬性可以直接像這樣訪問-->
{{name}}
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",["$scope",function($scope){
$scope.name = "lins";
}]);
</script>
$rootScope
$rootScope也是作用域,不過是每個app有且只有一個的 根作用域 ,由於在每個控制器中都能訪問這唯一的一個作用域,因此可以用來跨控制器傳值。
例子:
<div ng-app="myApp">
<div ng-controller="myCtrl1 as mc1">
<!--不能在頁面上直接向rootScope中存值,必要時可以通過事件中轉-->
<input type="text" ng-change="mc1.txt_change()" ng-model="mc1.text">
</div>
<div ng-controller="myCtrl2 as mc2">
<!--在頁面上取值時,與$scope用法相似,直接寫屬性名就可以-->
{{text}}
<button ng-click="mc2.btn_click()">console.log</button>
</div>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl1",["$rootScope",function($rootScope){
var mc1 = this;
mc1.txt_change = function(){
//在JS代碼中,需要將$rootScope服務注入到想要使用的controller中
//就可以像使用其他對象一樣的存值方式和取值方式。
$rootScope.text = mc1.text;
}
}]);
myApp.controller("myCtrl2",["$rootScope",function($rootScope){
var mc2 = this;
mc2.btn_click = function(){
console.log($rootScope.text);
}
}]);
</script>
$http
$http是AngularJS對ajax的封裝,用來向服務器發送請求。
GET請求
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",["$http",function($http){
var mc = this;
$http({
url:"http://127.0.0.1/param?name=lins&age=24",
method:"GET"
}).then(function(resp){
//成功時的回調函數
//resp.data就是服務器以json形式發送的對象
console.log(resp.data);
//服務器返回的數據可以交給AngularJS進行管理,以便在頁面上渲染
mc.users = resp.data;
},function(err){
//失敗時的回調函數
});
}]);
POST請求
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",["$http",function($http){
var mc = this;
$http({
url:"http://127.0.0.1/httpServer/param",
method:"POST",
data:"name=lins&age=24",
//配置請求方式爲模擬表單
headers:{"Content-Type":"application/x-www-form-urlencoded"}
}).then(function(resp){
console.log(resp.data);
mc.users = resp.data;
},function(err){
//失敗時的回調函數
});
}]);
從頁面收集參數**
<html>
<head>
<meta charset="UTF-8">
<title>從頁面收集參數</title>
<script src="https://cdn.bootcss.com/angular.js/1.6.3/angular.js"></script>
<script src="querystring.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl as mc">
用戶名:<input type="text" ng-model="mc.user.username"><br>
密碼:<input type="password" ng-model="mc.user.password"><br>
性別:
<input type="radio" ng-model="mc.user.gender" value="male">男
<input type="radio" ng-model="mc.user.gender" value="female">女
<button ng-click="mc.submit()">提交</button>
<br>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",["$http",function($http){
var mc = this;
mc.submit = function(){
$http({
url:"http://127.0.0.1/httpServer/param",
method:"POST",
data:querystring.stringify(mc.user),
headers:{"Content-Type":"application/x-www-form-urlencoded"}
});
};
}]);
</script>
</body>
</html>
過濾器
有時,我們想要某些數據,在顯示到頁面上之前進行統一處理。這時,再依賴控制器實現,往往過於繁瑣。AngularJS爲了解決這種問題,提出了過濾器的概念。
貨幣格式過濾器currency
<div ng-app="myApp" ng-controller="myCtrl as mc">
<!--使用過濾器時,使用|與原始數據分隔-->
<span>{{mc.c1 | currency}}</span>
<!--傳參數時,使用:分隔-->
<span>{{mc.c2 | currency:"¥"}}</span>
<span>{{mc.c3 | currency:"$":4}}</span>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.c1 = 15;
mc.c2 = 26.7;
mc.c3 = 35.66;
})
</script>
在JS中使用過濾器
過濾器的一般用法是在頁面上(視圖層)直接使用,同時,它也可以作爲一種服務注入到控制器中使用。
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function($filter){
//語法:$filter("過濾器名字")(要過濾的數據,參數1,參數2,...)
console.log($filter("currency")(15,"¥",3));
});
日期格式過濾器
<div ng-app="myApp" ng-controller="myCtrl as mc">
<span>{{mc.now | date:"yyyy-MM-dd HH:mm:ss"}}</span>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.now = new Date();
})
</script>
數組排序過濾器
<div ng-app="myApp" ng-controller="myCtrl as mc">
<ul>
<!--根據數組元素本身從小到大排序-->
<li ng-repeat="i in mc.array | orderBy">{{i}}</li>
</ul>
<ul>
<!--根據數組元素本身從大到小排序-->
<li ng-repeat="i in mc.array | orderBy:'-'">{{i}}</li>
</ul>
<table border="1">
<tr>
<td>姓名</td>
<td>年齡</td>
</tr>
<!--根據數組元素某個屬性從小到大排序-->
<tr ng-repeat="u in mc.users | orderBy:'age'">
<td>{{u.name}}</td>
<td>{{u.age}}</td>
</tr>
</table>
<br>
<table border="1">
<tr>
<td>姓名</td>
<td>年齡</td>
</tr>
<!--根據數組元素某個屬性從大到小排序-->
<tr ng-repeat="u in mc.users | orderBy:'-age'">
<td>{{u.name}}</td>
<td>{{u.age}}</td>
</tr>
</table>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function(){
var mc = this;
mc.array = [1,3,2,8,5];
mc.users = [
{name:"lins",age:24},
{name:"suns",age:18},
{name:"zhang3",age:35}
];
});
</script>
數組查找過濾器
<div ng-app="myApp" ng-controller="myCtrl as mc">
<ul>
<!--根據數組元素本身進行查找-->
<li ng-repeat="i in mc.array | filter:1">{{i}}</li>
</ul>
<table border="1">
<tr>
<td>姓名</td>
<td>年齡</td>
</tr>
<!--根據數組元素的某個屬性進行查找-->
<tr ng-repeat="u in mc.users | filter:{name:'s'}">
<td>{{u.name}}</td><td>{{u.age}}</td>
</tr>
</table>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
myApp.controller("myCtrl",function($filter){
var mc = this;
mc.array = [11,12,23,45,51];
mc.users = [
{name:"lins",age:24},
{name:"suns",age:18},
{name:"licy",age:24}
];
})
</script>
自定義過濾器
有時,AngularJS提供的過濾器並不能滿足我們的需求。這時,我們就可以自定義過濾器。
<div ng-app="myApp" ng-controller="myCtrl as mc">
<div>{{mc.test | price}}</div>
</div>
<script>
"use strict"
var myApp = angular.module("myApp",[]);
//myApp.filter("過濾器名字",function(){
// return 過濾器實現函數(原始數據,所需參數1,...){
// return 處理完的數據;
// }
});
myApp.filter("price",function(){
return function(text,prefix,count){
prefix = prefix || "¥";
count = count || 2;
//在這裏將處理好的數據進行返回
return prefix + parseFloat(text).toFixed(count);
}
});
myApp.controller("myCtrl",function(){
var mc = this;
mc.test = 5;
})
</script>
AngularJS高級語法
路由
路由描述了url和視圖的映射關係。
AngularJS對路由的實現
<script src="https://cdn.bootcss.com/angular-ui-router/1.0.3/angular-ui-router.js"></script>
AngularJS的路由系統,由一個主頁面和若干個子頁面構成。所有的JS代碼和CSS代碼放在主頁面上,子頁面僅僅完成製作視圖的功能。
AngularJS對路由的實現是通過URL HASH實現的,根據訪問地址中的HASH部分,唯一的確定一個子頁面,並使用AJAX的方式將子頁面中的內容拉取到主頁面上的某個局部進行展示。
主頁面的製作步驟:
- 定義ng-app。
- 定義子頁面的顯示區域 ui-view 。
- 配置路由規則。
- 完成控制器的製作。
子頁面的製作步驟:
- 繪製視圖。
基本路由
主頁面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>基本路由主頁面</title>
<script src="https://cdn.bootcss.com/angular.js/1.6.3/angular.js"></script>
<script src="https://cdn.bootcss.com/angular-ui-router/1.0.3/angular-ui-router.js"></script>
</head>
<body>
<div ng-app="myApp">
<a href="javascript:" ui-sref="a">路由1</a>
<a href="javascript:" ui-sref="b">路由2</a>
<div ui-view></div>
</div>
<script>
//主頁面:Controller層
//註冊app,提供路由配置"ui.router"
var myApp = angular.module("myApp",["ui.router"]);
//書寫路由配置信息,需要至少$stateProvider,$urlRouterProvider
myApp.config(function($stateProvider,$urlRouterProvider){
//定義默認跳轉,填寫的是要默認跳轉的路由的url
$urlRouterProvider.otherwise("/route1");
//其他路由跳轉規則
$stateProvider
.state("a",{
url:"/route1",//地址欄顯示的路徑信息
templateUrl:"route1.html"//要跳轉到視圖的路徑
})
.state("b",{
url:"/route2",//地址欄顯示的路徑信息
templateUrl:"route2.html",//要跳轉到視圖的路徑
controller:"route2Ctrl",//在路由2中生效的Controller
controllerAs:"c2"//controller的別名
});
});
myApp.controller("route2Ctrl",function(){
this.test = "HelloWorld";
})
</script>
</body>
</html>
route1.html:
<div>這是路由1的頁面</div>
route2.html:
<div>
這是路由2的頁面
<div>
{{c2.test}}
</div>
</div>
樣式控制
ui-sref-active 是一個根據當前路由子頁面控制樣式的屬性,屬性值是一個class。它可以被加在含有ui-sref屬性的標籤或者其父標籤上。 當用戶切換到對應的路由時,ui-sref-active所在的標籤會被加入其屬性值所對應的class 。
<div ng-app="myApp">
<!--當前路由子頁面爲路由1時,這個a標籤被加入名爲active的class。-->
<a ui-sref-active="active" href="javascript:" ui-sref="a">路由1</a>
<!--當前路由子頁面爲路由2時,這個div標籤被加入名爲active的class。-->
<div ui-sref-active="active"><a href="javascript:" ui-sref="b">路由2</a></div>
<div ui-view></div>
</div>
動態路由(路由傳參)
AngularJS中的路由傳參是利用url傳參,因此主要是在url相關部分進行配置。
動態路由配置步驟:
-
在路由規則中的url部分使用
/:
指定參數的名字。 比如配置爲url:"/user/:name/:age"
,那麼當我們訪問“/user/lins/18”時,“lins”就會被賦值到name中,18就會被賦值到age中。 -
在ui-sref中進行參數傳遞。 語法:
<a ui-sref="路由名稱({參數1名:參數1,參數2名:參數2})" href="javascript:">鏈接文本</a>
。
下面的例子模擬了一個用戶查詢:在主頁面將一個固定的用戶id傳遞到user頁面展示出來,在home頁面(首頁)將要查詢用戶的id傳遞到user頁面展示出來。
主頁面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/angular.js/1.6.3/angular.js"></script>
<script src="https://cdn.bootcss.com/angular-ui-router/1.0.3/angular-ui-router.js"></script>
</head>
<body>
<div ng-app="myApp">
<a ui-sref="home" href="javascript:">首頁</a>
<!--固定參數傳遞:直接使用字符串形式-->
<a ui-sref="user({id:'456'})" href="javascript:">用戶</a>
<div ui-view></div>
</div>
<script>
myApp = angular.module("myApp",[ "ui.router"]);
myApp.config(function($stateProvider,$urlRouterProvider){
//定義默認跳轉
$urlRouterProvider.otherwise("home");
//其他跳轉規則
$stateProvider
.state("home",{
url:"/home",
templateUrl:"home.html",
controller:"HomeCtrl",
controllerAs:"hc"
})
.state("user",{
//配置該如何從中解析參數
//使用:參數名來匹配相應位置的參數
url:"/user/:id",
templateUrl:"user.html",
controller:"UserCtrl",
controllerAs:"uc"
})
});
myApp.controller("HomeCtrl",function(){
});
//子頁面user中,需要向的controller中注入$stateParams服務,用於從地址中解析參數
myApp.controller("UserCtrl",function($stateParams){
this.id = $stateParams.id;
});
</script>
</body>
</html>
home頁面:
<div>
這是主頁
<input type="text" ng-model="hc.id">
<!--動態參數傳遞:直接使用控制器的屬性-->
<a ui-sref="user({id:hc.id})" href="javascript:">
<button type="button">查詢</button>
</a>
</div>
user頁面:
<div>
這是用戶詳情頁
<div>這是id爲{{uc.id}}的用戶的用戶詳情</div>
</div>
補充
多頁面應用和單頁面應用的詳細對比
多頁面應用
組成一個應用的每個頁面,幾乎是相互獨立的。在加載每張頁面時,僅僅加載這個頁面所需的CSS和JS。
優點:
- 進行首次頁面加載時僅需加載這個頁面所需資源,因此速度較快。
- 因爲頁面是完整的從服務器傳送到客戶端,因此便於搜索引擎抓取。
- 自動實現“前進”和“後退”的功能。
缺點:
- 進行頁面跳轉時,整張頁面從零開始加載,耗時較長。
- WEB瀏覽器和手機APP需要兩套不同的後端代碼,不利於前後端分離。
單頁面應用
整個應用僅有一個主頁面。在加載主頁面時,加載全部所需CSS和JS;在進行頁面切換時,無需重新加載CSS和JS。
優點:
- 在首次頁面加載完成後,頁面切換效率較高,有較好的用戶體驗。
- WEB瀏覽器和手機APP需要的後段代碼幾乎完全相同,可以較好的實現前後端分離。
缺點:
- 頁面首次加載耗時較多,因此必須進行JS和CSS壓縮來緩解。
- 服務器到客戶端的通信是不連續的,不利於搜索引擎抓取。
- 需要利用URL HASH和頁面棧等技術實現“前進”和“後退”的功能。