之前在C#中也經常使用MVC開發模式,對其的使用有一定的了解,但是現在需要學習AngularJS,這是純前台的JS代碼,那么為什么需要學習這個呢,就是想將驗證這里全部在前台執行,不需要在后台代碼里面出現驗證。項目需要,自己還是得下功夫看下,不要求全部會,簡單的使用就OK.
AngularJS最適於開發客戶端的單頁面應用,不是功能庫,是用來開發動態網頁的框架,專注於擴張HTML的功能,提供動態數據綁定。依賴注入,沒想到這里也有這個,之前是在IOC中聽到過,自己也研究了下,但是對其理解不是很好,這里的依賴注入是讓我們實現關注點分離的方法,意味着你可以非常自由的申明組件,然后你可以通過任意其它組件,呼叫一個它的實例,然后授權,你不需要知道載入順序,文件位置等。只需要提供它所需要的東西就OK。
AngularJS的四大功能
- MVC
將后台的MVC模式寫入了前端語言中。我總覺得前端語言將來會很叼,從node.js開始我就又一種這樣的感覺。可能在很久之后取代后端語言不是沒有可能的。
- 模塊化
就是一系列函數的集合,當應用被啟動時,這些函數就會被執行。主要利用angular.module來定義模塊。也是Angular.js的亮點。
- 指令屬性
我自己的理解就是比html標簽更加具有能力的指令標簽;
- 雙向數據綁定
傳統的數據綁定是單向綁定,數據只能從model和controller生成需要的html,但是不能返過來使用。只是單方向的。雙向數據綁定:也就是說我在前面填寫,后面直接生成代碼,將填寫的顯示出來。雙向的意思就是如果view修改了屬性值,那么model機會看到這個改變。相反也是一樣的。
View---->Model
<!doctype html> <html ng-app> <head> <meta charset="utf-8"> <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script> <script src="main.js"></script> </head> <body> Your name:<input type="text" ng-model="yourname"> <hr> Hello {{yourname||"zhanghui"}}! </body> </html>
Model----->View
<!doctype html> <html ng-app="AppModule"> <head> <meta charset="utf-8"> <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script> <script src="main.js"></script> </head> <body> Your name:<input type="text" ng-model="yourname"> <hr/> Hello {{yourname||"zhanghui"}}! <hr/> <div ng-controller="MyController"> {{person.name}} <hr/> <h5>{{clock}}</h5> </div> </body> </html>
var myApp=angular.module("AppModule",[]); myApp.controller('MyController',function($scope){ $scope.person={name:"Ahui"}; //申明了一個函數 var updateClock=function(){ $scope.clock=new Date(); }; //申明一個計時器 var timer=setInterval(function(){ $scope.$.apply(updateClock); },1000); updateClock(); });
AngularJS語法--指令屬性
什么是指令屬性呢,‘指令屬性’就是綁定在DOM元素上的函數,它可以調用方法,定義行為,綁定controller及$scope對象,操作DOM等。當瀏覽器啟動開始解析HTML時,DOM元素上的指令屬性就會和其它屬性一樣被解析。
當一個Angular.JS應用啟動時,Angular.JS編譯器就會遍歷DOM樹(從有ng-app指令屬性開始),解析HTML尋找這些指令屬性的函數,找到之后就會將其收集,排序,按照優先級順序被執行。(每個指令屬性都有優先級),這些就是Angular.js應用動態性和響應能力的基礎。
在Angular.JS應用中,我們用指令屬性來將行為綁定到DOM上,指令屬性的使用,是一個應用能否擁有動態性,響應能力的關鍵。
ng-model:
<input ng-model="name" name="Name" placeholder="輸入你的名字"/> <div> {{name}} </div>
我們可以看到它是動態顯示的。通過F12可以發現在下面有個class=”ng-binding”,我猜測應該就是將其綁定起來。
這樣實現了動態的綁定,ng-model指令屬性被用來將DOM文本輸入框的值,跟controller里的$scope model綁定起來。其實里面就是在這個值上面綁定了一個$watch函數(類似與JS中的監聽事件),$watch()函數在運行在Angular.js的事件循環里,讓其Angular.js能夠對DOM進行相應的更新。還有我們的表達式 {{表達式}},也會死使用那個函數給括號內的表達式注冊了一個監聽器。
ng-init:是一個在啟動時運行的函數(在程序進入運行階段之前),它讓我們能夠在程序運行前設定初始變量的值:
ng-click:給DOM元素注冊一個點擊事件的監聽器此時DOM元素上有點擊事件發生,Angular.js就會執行表達式的內容,並相應地更新View;也可以利用ng-click來調用controller里寫好綁定到$scope上的函數。
<h5 ng-controller="MyController"> <button ng-click="sayHello()">Say hello</button> </h5>
app.controller("MyController",function($scope){ $scope.sayHello=function(){ alert("Hello Word!"); } });
ng-show/ng-hide:根據賦值表達式的值的真假性,來顯示和隱藏它們所屬的那一部分DOM;以編程的方式顯示或隱藏一個元素。
ng-repeat:此指令遍歷一個數據集合的每個數據元素,加載HTML模版把數據渲染出來,被重復使用的模版元素,就是我們綁定這個屬性的DOM元素,每一個使用模版渲染的DOM元素都有自己的scope。
- 看下面的例子
app.controller("MyController",function($scope){ $scope.sayHello=function(){ alert("Hello Word!"); } //定義了集合,就是一些json格式 $scope.roommates=[ {name:'Ari'}, {name:'Q'}, {name:'Sean'}, {name:'Anand'} ] //定義了鍵值對集合 $scope.people={ 'Ari':'orange', 'Q':'purple', 'Sean':'green' } });
<ul> <li ng-repeat="person in roommates">{{person.name}}</li> </ul> <hr/> <ul> <li ng-repeat="(name,color) in people">{{name}}喜歡的是{{color}}</li> </ul>
這里我們可以發現其實就是將集合里面的值遍歷出來,給人的第一感覺就是像foreach(),其實里面應該是一樣的。“person in roommates”roommates就是后端給的集合,這里在用person一個一個的輸出來。
{{}}:雙括號代表數據的顯示,叫做模版表達式,就和我們c#中前台的@{}一樣,中間可以寫C#代碼,這個效果是一樣的。
angular.module:定義其angular模塊,
var myModule=angular.module("MyModule",[]);
創建了一個叫myModule模塊,那么如何去使用它了,我們看下面的代碼,使用其指令系統就可以對此模塊進行調用。這里是后面一切的前提,我們只有在頁面上標記了ng-app之后,才能寫之后的控制器等一系列操作。
<html ng-app="MyModule">
ngClass:可以動態的更新類;
ngBind:可以實現雙向的數據綁定;
Scopes:這個關鍵字就和我們后端MVC中的model模型一樣,在Controller和VIew直接傳遞數據,是一個把View(一個dom元素)連接到controller上的對象,實際上就是一個js對象。c,v都可以訪問它,它在二者直接傳遞數據信息。每一個Angular應用都會有一個$rootScope,是最頂級的scope,對應於含有ng-app指令屬性的那個dom元素。
ng-controller:Angular中的控制器。在js文件中定義,就可以直接在html頁面中寫。如下所示:
<div ng-controller="MyController"> {{person.name}} </div>
ng-controller指令給所在的dom元素創建了一個新的$scope對象,並將這個$scope對象包含進外層dom元素的$scope對象里,
MyModule.controller('MyController',function($scope){ $scope.person={ name:"ahui" }; });
只要在有ng-controller=’MyController’屬性的DOM元素的任何子元素里訪問這個person對象,因為它在 $scope上。
這里所有的scope都遵循原型繼承,意味着它們都能訪問父scope們,對於任何的屬性和方法,若當前scope上找不到那就回溯,到父類找,一直往上回溯。一直到$rootScope上。
注意:上面的是MyModule是我們之前在js文件中聲明的,在HTML頁面中也標記了,只有這樣頁面才會使用指令系統。
ng-click:將DOM元素的鼠標點擊事件(mousedown瀏覽器事件)綁定到一個方法上,當瀏覽器在該DOM元素上鼠標觸發點擊事件時,此時綁定的方法就被調用。
<div ng-controller="ClickController"> <button ng-click="add(1)" class="button">Add</button> <button ng-click="subtract(1)" class="button">Subtract</button> <h4>值為:{{counter}}</h4> </div>
//測試onclick事件 myApp.controller("ClickController",function($scope){ $scope.counter=0; $scope.add=function(amount){ $scope.counter+=amount; }; $scope.subtract=function(amount){ $scope.counter-=amount; }; });
不論是按鈕還是鏈接都會被綁定到包含它們DOM元素的controller所有的$scope對象上。
原型繼承:
這里的原型繼承實際上就和我們之前在js中里面的原型繼承是一樣的道理。
//父類 myModule.controller("ParentController",function($scope){ $scope.person={greeted:false}; }); //子類,聲明了一個方法sayHello()。 myModule.controller("ChildController",function($scope){ $scope.sayHello=function(){ $scope.person.greeted=true; //原型繼承,直接調用了父類的方法 } });
前台的寫法:
<div ng-controller="ParentController"> <div ng-controller="ChildController"> <input type="text" ng-model="person.name" placeholder="Name"></input> <a ng-click="sayHello()">Say Hello</a> </div> {{person}} </div>
我們可以發現子類修改了父類中的屬性,這就是原型繼承。
原生支持AJAX
Angular.js原生支持AJAX,這樣就具有了與一個或多個服務器來回發送請求的能力,這種應用需要跟服務器瀏覽,獲取數據和更新數據。通過服務$http來支持AJAX;
所有的Angular.js的核心服務都用$前綴
$http:它接受一個設置對象,其中指定了如何創建HTTP請求,它將返回一個承諾,其中提供倆個方法:success方法和error方法。它通過XMLHttpRequest對象或JSONP與遠程HTTP服務進行交流。
$http({ method:'JSONP', url:'http://api.openbeerdatabase.com/v1/beers.json?callback=JSON_CALLBACK' }).success(function(data,status,headers,config){ //輸出正確值 }).error(function(data,status,headers,config){ //輸出錯誤值 });
AngularJS中的表達式
表達式都運行在調用它們的scope里,所以一個表達式可訪問並操作其scope上的一切,由此你可以使用表達式遍歷其scope的屬性,調用scope里的函數,或者對scope中的變量進行數學運算。