概述:
適用於以數據操作為主的SPA(Single Page Application)應用。
基於jQuery對傳統的DOM操作進行進一步的封裝---使用MVC操作代替了所有的DOM操作。
不再是“先查找元素再操作元素”,
所有的操作都是以“業務數據“為中心
搭建環境:
使用 AngularJS 的步驟:
1.引入必需的js文件 : angular.js
2.為父元素聲明ngApp屬性(這里的父元素一般指html)(系統會自動載入或啟動一個NG應用,這個ngApp是唯一的,只能有一個)
3.為父元素內部使用angularJS相關內容
4.
<!DOCTYPE html> <html lang="en" ng-app="haixin"> <head> <meta charset="UTF-8"> <title>ng</title> <!--[if lte IE 9]> <script src="public/js/html5shiv.min.js"></script> <script src="public/js/respond.min.js"></script> <![endif]--> <script src="public/js/jquery-2.2.3.min.js"></script> <script src="public/js/bootstrap.js"></script> <script src="public/js/angular.js"></script> <link rel="stylesheet" href="public/css/bootstrap.css"> <link rel="stylesheet" href="public/css/animation.css"> </head> <body> </body> </html>
ng四大特性:
1.采用MVC模式,頁面中再也無需出現DOM操作。
2.雙向數據綁定。
3.依賴注入
4.模塊化設計
ng四大特性之一MVC模式:
(1)Model: 模型,指業務數據,web項目中由js變量擔當model。
(2)View: 視圖,用戶界面,HTML
(3)Controller: 控制器,Function
ng指令:
AngularJS 中ng模塊提供的指令(directive)
(1) ngApp:自動載入/啟動一個AngularJS應用
(2) ngInit:用於聲明Model(模型)變量
(3) ngController:創建一個控制器對象的實例
(4) ngBind:在當前元素的innerHTML上輸入指定的表達式的值
(5) ngRepeat:為HTML增加循環功能,循環輸出當前元素
(6) ngIf:為HTML增加選擇功能,只有在表達式值為true時,當前元素才添加到DOM樹
(7) ngSrc:解決img等標簽的src屬性中包含{{}}產生的問題
語法: <img ng-src="路徑/{{表達式}}"/>
(8) ngClick: 為元素綁定監聽函數(不是全局函數,而是Model函數)
語法: <ANY ng-click="模型函數()">
(9) 使用$scope.模型函數名 = function(){}格式來聲明模型函數
(10) ngStyle: 賦值為一個Model對象,用於為當前元素指定樣式
(11) ngShow/ngHide: 通過display:none/block來控制當前元素是否顯示
(12) ngDisabled: 賦值為true/false,可以控制當前元素是否禁用
(13) ngChecked: 賦值為true/false,可以控制當前元素是否選中
Angular中聲明變量——Model數據
有兩種方式可以聲明Model變量:
(1)使用ngInit指令聲明
ngInit 指令可以聲明為HTML元素的屬性或樣式
ngInit 指令聲明的Model變量可以先使用再聲明
ngInit 指令可以一次聲明多個Model變量,用分號隔開即可
ngInit 指令可以聲明哪些類型的Model變量:
number、string、boolean、對象、數組、對象的數組
注意:使用ngInit定義Model變量時不能使用new關鍵字;此方法
把View和Model混雜在一起,不推薦使用!
(2)使用Controller創建Model變量——推薦使用
創建Module <= 創建Controller <= 創建Model變量
注意:新版本的Angular要求控制器必須聲明在一個模塊中!
具體步驟:
1)聲明一個自定義的模塊(module)
angular.module('模塊名', [ ])
2)在當前AngularJS應用中注冊自定義模塊
ng-app="模塊名"
3)在自定義模塊中創建Controller函數,其中創建Model數據
$scope.模型變量名 = 值
4)在View中創建Controller對象的實例,指定其作用范圍
<標簽 ng-controller=“控制器名”>...控制器的有效范圍...</標簽>
5)在控制器的作用范圍內輸出Model變量
可以使用{{}}輸出Model變量的值開發人員來編寫
$scope $rootScope
(1)每個控制器的實例都對應一個作用范圍對象,即$scope
(2)在控制器中聲明的Model數據,必須保存在一個作用范圍內
(3)一個HTML中可以聲明多個控制器實例,每個控制器都有自己的作用范圍,這些范圍內的數據彼此隔離不會互相影響,
可以由不同開發人員來編寫
(4)為了在多個控制器間共享數據,可以將Model數據保存在一個“全局作用范圍內”——$rootScope——整個AngularApp中
有且只有一個$rootScope對象,且此對象是所有 的$scope的父作用域對象
(5)作用域對象間可以實現繼承,只需要將某個控制器實例聲明在另一個控制器實例的有效作用域內部即可。
模塊:
基本語法:
<script> angular.module("haixin",[]).controller("方法名",function($scope){ $scope.mobile1=""; $scope.mobile2=""; }) </script>
控制器:
定義對象屬性:
<script> function studentController($scope){ $scope.student={ stu1:"zhangsan", stu2:"lisi" } } </script>
控制器:
定義方法:
<script> function studentController($scope){ $scope.student={ sName1:"zhangsan", sName2:"lisi", allName:function(){ var n; n=$scope.student; return n.sName1+""+n.sName2; } } } </script>
PS:小練習:
(1)創建一個新的頁面,其中聲明module、controller、model變量:一個學生對象,其中包含sname、gender、birthday、
score等屬性,在view中顯示這些model數據
(2)創建一個新的頁面,其中聲明module、controller、model變量:5個分數組成的數組,在view中的一個列表中輸出這5個數字
(3)五個商品的數據顯示在View中的table元素中,使用ngRepeat指令進行循環
案例答案:
<html lang="en" ng-app="haixin"> <body> <section ng-controller="practice"> <p>{{obj}}</p> <ul> <li ng-repeat="k in arr">{{k}}</li> <li ng-repeat="(k,v) in arr">{{k}}:{{v}}</li> </ul> </section> <section ng-controller="commodity"> <table class="table table-bordered table-hover text-center"> <th>序號</th><th>商品名字</th> <th>商品價格</th><th>商品圖片</th> <tr ng-repeat="i in arr1"> <td>{{$index+1}}</td> <td>{{i.name}}</td> <td>{{i.price}}</td> <td><img ng-src="{{i.img}}" width="60"></td> </tr> </table> <button class="btn btn-block btn-primary" ng-click="add()">點擊加載</button> </section> <script> angular.module("haixin",[]).controller("practice",function($scope){ $scope.obj = new Object(); $scope.obj.name = "Tom"; $scope.obj.gender ="boy"; $scope.obj.birthday = "4.18"; $scope.arr=[10,20,30]; }).controller("commodity",function ($scope) { $scope.arr1=[ {name:"商品1",price:"77",img:"images/1.jpg"}, {name:"商品2",price:"33",img:"images/2.jpg"}, {name:"商品3",price:"55",img:"images/3.jpg"} ]; $scope.add=function () { for(var i=0;i<3;i++){ var arr2 ={}; arr2.name="商品"; arr2.price="11"; arr2.img="images/"+(1+i)+".jpg"; $scope.arr1.push(arr2); } } }) </script> </body> </html>
ng四大特性--雙向數據綁定:
方向一:把Model數據綁定到View上
把Model數據綁定到View上后,任何Model數據的修改,都會自動更新到View上({{ }}、ngBind、ngRepeat、
ngSrc...都實現了方向1的綁定)
方向二:把View綁定到Model上
把View數據綁定到Model后,任何View數據的修改,都會自動更新到Model上
此后不論任何時候,只要View中的數據一修改,Model中的數據會自動隨之修改。實現方法: 只有ngModel指令。
可以使用$scope.$watch(‘模型變量名’, fn)監視一個模型變量值的改變;單行文本輸入域、多行文本輸入域、下拉框、
單選按鈕控件默認會把自己的value屬性值綁定到一個Model變量;復選框會把一個true/false值綁定到一個Model變量。
ng模塊中提供的服務(service)
(1)$rootScope: 用於在不同的控制器間共享數據
(2)$interval: 提供周期性定時器服務
(3)$interval.cancel(t):清除定時器
(4)$timeout: 提供一次性定時器服務
(5)$http: 發起異步的Ajax請求服務
定時器小案例:input值改變的時候,控制台也會改變,若只寫input和P的時候,input值改變的時候P的內容也跟着改變。
代碼如下:
<input type="text" ng-model="Uname"> <p>{{name}}</p> <script> $scope.$watch("Uname",function () { console.log($scope.Uname); }) </script>
PS:小練習
1:簡易版的點擊次數計算器
2:簡易版的輪播廣告
3:用Bootstrap組件制作一個進度條(每隔0.2s,前進10%)取消定時:$interval.cancel(t);
4:簡易版的購物車
5:同意使用條款,則可以注冊,否則禁止注冊
6:簡易版模擬QQ選擇切換頭像
7:全選或取消全選(PS:4,5,6,7這四個小練習是雙向數據綁定了,直接加ng指令就可實現。下面案例中圖片
名字一律為n.jpg【n 為正整數】)
案例代碼如下:
<html lang="en" ng-app="haixin"> <body> <section class="container"> <section ng-controller="lunbo"> <p>{{n}}</p> <button class="btn btn-danger" ng-click="fn()">點擊加一</button><br/> <img ng-src="images/{{img}}.jpg" alt="" width="300"> <button class="btn btn-success" ng-click="prev()">上一個</button> <button class="btn btn-success" ng-click="next()">下一個</button> </section> <section class="progress" ng-controller="jindutiao"> <div class="progress-bar" role="progressbar" aria-valuenow="85" aria-valuemin="0" aria-valuemax="100" ng-style="myStyle"></div> </section> <section ng-controller="a2"> <form> 單價:<input type="number" placeholder="請輸入價錢" ng-model="price"> 數量:<input type="number" placeholder="請輸入數量" ng-model="num"> 小計:<span>{{price*num}}</span> </form> <input type="checkbox" ng-model="agree">我同意本站的使用條款 <button class="btn btn-success" ng-disabled="!agree">提交注冊</button> <button class="btn btn-danger" ng-if="agree">提交注冊</button> <button class="btn btn-primary" ng-show="agree">提交注冊</button> <select ng-model="pic"> <option value="images/1.jpg">帥鍋</option> <option value="images/2.jpg">蕾女</option> <option value="images/3.jpg">大爺</option> <option value="images/4.jpg">大叔</option> </select> <span><img ng-src={{pic}} width="200"></span> <aside> <input type="checkbox" ng-checked="checkAll">A <input type="checkbox" ng-checked="checkAll">B <input type="checkbox" ng-checked="checkAll">C <input type="checkbox" ng-model="checkAll"> <span ng-hide="checkAll">全選</span> <span ng-show="checkAll">取消全選</span> </aside> </section> </section> <script> angular.module("haixin",[]).controller("lunbo",function ($scope) { $scope.n = 10; $scope.fn=function () { $scope.n++; }; $scope.img =1; $scope.next=function () { $scope.img++; if($scope.img==5){ $scope.img=1; } }; $scope.prev=function () { $scope.img--; if($scope.img<1){ $scope.img=4; } } }).controller("jindutiao",function ($scope,$interval) { $scope.n=10; $scope.myStyle={"width":"0%"}; var t = $interval(function () { $scope.myStyle.width=$scope.n+"%"; $scope.n+=10; if($scope.n==90){ $interval.cancel(t); } },200) }) </script> </body>
ng四大特性之—依賴注入:
依賴: Driver對象的創建和運行必需一個car對象,稱為Driver對象“依賴於”Car對象。依賴注入體現着“最少知識法則”
依賴對象的解決方法:
(1)主動創建
var c=new Car(); //創建被依賴的對象 var d=new Driver(c); //使用被依賴的對象
(2)被動注入(inject)
一般由特定框架來創建Driver對象,發現其依賴於一個Car對象,框架自動創建被依賴的Car對象——稱為“依賴注入”。
依賴注入的典型例子:
angular.module.controller('控制器名', function( $scope, $http ){ })
注意:
控制器對象的構造函數是由AngularJS來調用的,不能手動調用
Angular會根據控制器對象的構造函數的形參名來創建依賴的參數對象——形參名不能隨意指定!
若控制器對象未聲明形參,則Angular不會傳遞任何實參進來
控制器對象的形參名(PS:此處的形參名是不能夠隨意定的)必需是Angular可識別的,但數量和順序都沒有限制—Angular會
根據每一個形參的名稱來查找創建被依賴的對象,並自動注入進來。
ng四大特性之—模塊化設計:
項目中,可以根據功能的不同,將不同的組件放置在不同的模塊中
AngularJS中有兩種模塊:
(1)AngularJS官方提供的模塊:ng、ngRoute、ngAnimate、ngTouch、....
(2)用戶自定義的模塊:userModule、productModule、orderModule、....
一個NG模塊中可以包含多個組件:
(1)controller組件:用於維護模型數據
(2)directive組件:用於在View中輸出/綁定Model數據
(3)service組件:用於在不同的控制器中提供某種函數服務
(4)filter組件:用於對View中輸出的數據進行格式化
……..
Filter組件 (過濾器):
用於Model數據在View中呈現時進行某種格式的篩選/過濾/格式化。
在View中使用過濾器時,需要借助於管道:|
ng模塊中提供的過濾器:(ps:HH指的是24小時制)
(1)lowercase:把數據格式化為小寫
(2)uppercase:把數據格式化為大寫
(3)number:把數字型數據格式化為三位一個逗號的字符串同時指定小數點位數 eg: {{price | number : 2 }}
(4)currency:把數字型數據格式化為貨幣格式的字符串,同時指定貨幣符號 eg: {{price | currency : '¥' }}
(5)date:把數字/Date型數據格式化為特定日期時間格式的字符串
<p>{{name | lowercase}}</p> <p>{{name | uppercase}}</p> <p>{{num | number:2}}</p> <p>{{num | currency:"¥"}}</p> <p>{{time | date:"yyyy年MM月dd日 HH時mm分ss秒"}}</p> <p>{{time | date:"yyyy-MM-dd HH:mm:ss"}}</p>
PS案例:點擊一個按鈕“加載員工數據”,向服務器發起異步的Ajax請求,獲取服務端的一段JSON數據,顯示在一個
表格中(注意數據格式);加載完數據后,按鈕即禁用/消失。
案例答案:
<!DOCTYPE html> <html ng-app="haixin"> <head lang="en"> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="../css/bootstrap.css"> </head> <body> <section class="container" ng-controller="a1"> <table class="table table-bordered table-hover"> <tr> <th>序號</th> <th>姓名</th> <th>工資</th> <th>入職日期</th> </tr> <tr ng-repeat="j in pro"> <td>{{$index+1}}</td> <td>{{j.ename}}</td> <td>{{j.salary |number}}</td> <td>{{j.hiredate |date:"yyyy年MM月dd日"}}</td> </tr> </table> <button ng-click="add()" class="btn btn-block btn-success" ng-disabled="tab">點擊</button> </section> <script src="../js/jquery-1.11.3.js"></script> <script src="../js/bootstrap.js"></script> <script src="../js/angular.js"></script> <script> angular.module("haixin",[]).controller("a1",function ($scope,$http) { $scope.tab = false; $scope.add=function () { $scope.tab = true; $http.get("1.json").success(function (data) { $scope.pro=data; }); } }) </script> </body> </html>
[ {"ename":"Tom", "salary":456765,"hiredate":22224352345}, {"ename":"Mary", "salary":232323,"hiredate":234798237823}, {"ename":"John", "salary":8875645,"hiredate":23423478923}, {"ename":"King", "salary":34325546,"hiredate":772374234333}, {"ename":"Allen", "salary":86756453234,"hiredate":237643274234} ]
Angular官方提供的模塊之二——ngRoute模塊
ngRoute模塊可以讓用戶自定義“路由字典”,自動解析請求URL中的路由地址,查找路由字典,自動發起異步AJAX請求,把獲取的結果放在當前頁面中。
值得注意的是,一定要在myApp的moudle中引用ng-route,同時要在文件中引用angular-route.js文件,否則不起作用
Route:路由,為到達目的地而經過的線路
(1)頁面URL形如: http://127.0.0.1/index.html#/路由地址
(2)瀏覽器首先請求基礎頁面(index.html),再解析URL中的路由地址
(3)查找路由字典,形如:
#/start =》 tpl/start.html
#/main =》 tpl/main.html
....
獲取當前URL中路由地址所對應的真實模板頁面的地址
(4)客戶端發起異步AJAX請求,獲取目標模板頁面,將服務器返回HTML片段(只含有幾個div),插入到當前的DOM樹上。
使用ngRoute模塊的步驟:
(1)創建唯一完整的頁面: index.html,引入angular.js和angular-route.js
(2)在index.html的body中使用ngView指令聲明一個容器元素,用於盛放模板頁面
(3)創建自定義模塊,聲明依賴於ng和ngRoute兩個模塊
(4)在當前模塊中使用ngRoute提供的對象配置路由字典
angular.module("haixin",[]).config(function($routeProvider){ $routeProvider.when("/路由地址", { templateUrl:"模板頁面URL" }).otherwise({ redirectTo:"/路由地址" }) })
(5)再創建幾個模板頁面,只需要有div元素即可
(6)測試路由字典的配置是否正確
使用ngRoute模塊需要注意的問題:
(1)由於模板頁面被客戶端請求后掛載在index.htmlDOM樹上,所以其中所有的圖片等外部資源文件的路徑必須相對於index.html,而不是模板頁面。
(2)使用ngRoute模塊時,無需為模板頁面中的某個元素單獨設置ngController,只需要在聲明路由字典時設置整個模板頁面所需要的控制器即可
.when('/路由地址', { templateUrl: 'xxx.html', controller: '控制器名' })
(3)在不同的模板頁面間跳轉可以采用兩種方式:·超鏈接方式:<a href="#/路由地址"></a>JS編程方式:<button ng-click="jump( )"></button>
$scope.jump = function(){ $location.path('/路由地址'); }
(4) index.html中,由於所有模板頁面都是在ngView中切換,ngView外面的內容會始終呈現。
官方提供的模塊——ngAnimate
ngAnimate可以支持JS、Transition、Keyframes動畫,但它本身未提供任何的動畫效果,而是為上面三種技術提供了相應的“動畫鈎子(Hooks)”
ng模塊中提供的指令:ngRepeat, ngInclude, ngIf, ngSwitch, ngShow, ngHide, ngView 和 ngClass默認都提供了動畫鈎子。
使用ngAnimate模塊調用其CSS Transition動畫鈎子的步驟:
(1) index.html引入angular.js和angular-animate.js。
(2) 自定義模塊中聲明依賴於ngAnimate模塊——特定的指令就會產生動畫鈎子。
(3) 為ngView聲明class,樣式中指定transition動畫;
可以看到ngAnimate為即將要離開的ngView添加了 ng-leave和ng-leave-active 兩個class,為即將要進入的ngView添加了 ng-enter和
ng-enter-active兩個class。為這四個class編寫特定的樣式即可。
(PS:這里只是普通的進出動畫,其實可以更炫點,每個頁面都有 進出的動畫,這個就是后期要研究的,可以充分利用C3一些特效)
.page { transition: all 2s linear; position: absolute; width: 100%; } /*要離開的ngView元素動畫開始時的樣式*/ .page.ng-leave { left: 0; } /*要離開的ngView元素動畫結束時的樣式*/ .page.ng-leave.ng-leave-active { left: -100%; } /*要進入的ngView元素動畫開始時的樣式*/ .page.ng-enter { left: 100%; top: 100%; transform: scale(0.9); } /*要進入的ngView元素動畫結束時的樣式*/ .page.ng-enter.ng-enter-active { left: 0; top: 0; }