?AngularJSAngularJS 是一個 MV* 框架,
? ? ? ?最適于開發客戶端的單頁面應用。它不是個功能庫,而是用來開發動態網頁的框架。它專注于擴展 HTML 的功能,提供動態數據綁定(data binding),而且它能跟其它框架(如 JQuery 等)合作融洽。1. 一個簡單示例通過下面的示例代碼,可以運行一個簡單的 AngularJS 應用:
在輸入框中嘗試輸入:
姓名:
通過瀏覽器訪問該頁面,在輸入框中輸入的內容會立即顯示在輸入框下面。說明:當網頁加載完畢,AngularJS 自動運行。ng-app 指令告訴 AngularJS ,div 元素是 AngularJS 應用程序的"所有者",相當于是個作用域的概率。ng-model 指令把輸入域的值綁定到應用程序變量 name。ng-bind 指令把應用程序變量 name 綁定到某個段落的 innerHTML。2. AngularJS 指令AngularJS 指令是擴展的 HTML 屬性,帶有前綴 ng- 。HTML5 允許擴展的(自制的)屬性,以 data- 開頭。AngularJS 屬性以 ng- 開頭,但是您可以使用 data-ng- 來讓網頁對 HTML5 有效。常見的指令ng-app 指令ng-app 指令初始化一個 AngularJS 應用程序。ng-init 指令ng-init 指令初始化應用程序數據,這個不常使用。通常情況下,不使用 ng-init。您將使用一個控制器或模塊來代替它。ng-model 指令ng-model 指令把元素值(比如輸入域的值)綁定到應用程序。ng-bind 指令ng-bind 指令把應用程序數據綁定到 HTML 視圖。示例:
在輸入框中嘗試輸入:
姓名:
ng-repeat 指令ng-repeat 指令會重復一個 HTML 元素:
循環對象:
除此之外,它還提供了幾個變量可供使用:$index 當前索引$first 是否為頭元素$middle 是否為非頭非尾元素$last 是否為尾元素樣式相關的指令ng-classng-class用來給元素綁定類名,其表達式的返回值可以是以下三種:類名字符串,可以用空格分割多個類名,如 ‘class1 class2’;類名數組,數組中的每一項都會層疊起來生效;一個名值對應的map,其鍵值為類名,值為boolean類型,當值為true時,該類會被加在元素上。與 ng-class 相近的,ng 還提供了ng-class-odd、ng-class-even 兩個指令,用來配合 ng-repeat 分別在奇數列和偶數列使用對應的類。這個用來在表格中實現隔行換色再方便不過了。ng-styleng-style 用來綁定元素的 css 樣式,其表達式的返回值為一個 js 對象,鍵為 css 樣式名,值為該樣式對應的合法取值。用法比較簡單:$scope.style = {color:'red'};
ng-style測試
ng-style測試
ng-show、ng-hide、ng-switch對于比較常用的元素顯隱控制,ng 也做了封裝,ng-show 和 ng-hide 的值為 boolean 類型的表達式,當值為 true 時,對應的 show 或 hide 生效。框架會用 display:block 和 display:none 來控制元素的顯隱。示例:
1
2
3
4
后一個 ng-switch 是根據一個值來決定哪個節點顯示,其它節點移除:
1
2
other
事件指令事件相關的指令有:ng-changeng-clickng-dblclickng-mousedownng-mouseenterng-mouseleaveng-mousemoveng-mouseoverng-mouseupng-submit對于事件對象本身,在函數調用時可以直接使用 $event 進行傳遞:
點擊
點擊
$scope.click = function($event){? ? ? ? alert($event.target);? ? ? ? //……………………} 表單指令表單控件類的模板指令,最大的作用是它預定義了需要綁定的數據的格式。這樣,就可以對于既定的數據進行既定的處理。formng 對 form 這個標簽作了包裝,對應的指令是 ng-form。從 ng 的角度來說, form 標簽,是一個模板指令,也創建了一個 FormController 的實例。這個實例就提供了相應的屬性和方法。同時,它里面的控件也是一個 NgModelController 實例。很重要的一點, form 的相關方法要生效,必須為 form 標簽指定 name 和 ng-controller ,并且每個控件都要綁定一個變量。 form 和控件的名字,即是 $scope 中的相關實例的引用變量名。
var TestCtrl = function($scope){? $scope.see = function(){? ? console.log($scope.test_form);? ? console.log($scope.test_form.a);? }}除去對象的方法與屬性, form 這個標簽本身有一些動態類可以使用:ng-valid 當表單驗證通過時的設置ng-invalid 當表單驗證失敗時的設置ng-pristine 表單的未被動之前擁有ng-dirty 表單被動過之后擁有form 對象的屬性有:$pristine 表單是否未被動過$dirty 表單是否被動過$valid 表單是否驗證通過$invalid 表單是否驗證失敗$error 表單的驗證錯誤其中的 $error 對象包含有所有字段的驗證信息,及對相關字段的 NgModelController 實例的引用。它的結構是一個對象, key 是失敗信息, required , minlength 之類的, value 是對應的字段實例列表。inputinput 控件的相關可用屬性為:name 名字ng-model 綁定的數據required 是否必填ng-required 是否必填ng-minlength 最小長度ng-maxlength 最大長度ng-pattern 匹配模式ng-change 值變化時的回調
input 控件,它還有一些擴展,這些擴展有些有自己的屬性:input type="number" 多了 number 錯誤類型,多了 max , min 屬性。input type="url" 多了 url 錯誤類型。input type="email" 多了 email 錯誤類型。checkbox是 input 的擴展,不過,它沒有驗證相關的東西,只有選中與不選中兩個值:ng-true-value、ng-false-value:
radio也是 input 的擴展。和 checkbox 一樣,但它只有一個值:
textarea同 inputselect它里面的一個叫做 ng-options 的屬性用于數據呈現。
可以加這個空值
在 $scope 中, select 綁定的變量,其值和普通的 value 無關,可以是一個對象:
顯示與值分別指定, x.v as x.name for x in o :
加入分組的, x.name group by x.g for x in o :
分組了還分別指定顯示與值的, x.v as x.name group by x.g for x in o :
如果參數是對象的話,基本也是一樣的,只是把遍歷的對象改成 (key, value) :
還有一些表單控件功能相關的指令:ng-src src 屬性ng-href href 屬性ng-checked 控制 radio 和 checkbox 的選中狀態ng-selected 控制下拉框的選中狀態ng-disabled 控制失效狀態ng-multiple 控制多選ng-readonly 控制只讀狀態以上指令的取值均為 boolean 類型,當值為 true 時相關狀態生效,道理比較簡單就不多做解釋。注意:上面的這些只是單向綁定,即只是從數據到模板,不能反作用于數據。要雙向綁定,還是要使用 ng-model 。3. AngularJS 過濾器過濾器(filter)正如其名,作用就是接收一個輸入,通過某個規則進行處理,然后返回處理后的結果。主要用在數據的格式化上,例如獲取一個數組中的子集,對數組中的元素進行排序等。過濾器通常是伴隨標記來使用的,將你 model 中的數據格式化為需要的格式。表單的控制功能主要涉及到數據驗證以及表單控件的增強。內置過濾器ng 內置了一些過濾器,它們是:currency(貨幣)、date(日期)、filter(子串匹配)、json(格式化json對象)、limitTo(限制個數)、lowercase(小寫)、uppercase(大寫)、number(數字)、orderBy(排序)。過濾器使用示例:// 使用currency可以將數字格式化為貨幣,默認是美元符號,你可以自己傳入所需的符號{{num | currency : '¥'}}// 參數用來指定所要的格式,y M d h m s E 分別表示 年 月 日 時 分 秒 星期,你可以自由組合它們。也可以使用不同的個數來限制格式化的位數。另外參數也可以使用特定的描述性字符串,例如“shortTime”將會把時間格式為12:05 pm這樣的。{{date | date : 'yyyy-MM-dd hh:mm:ss EEEE'}}$scope.func = function(e){return e.age>4;}{{ childrenArray | filter : 'a' }}// filter 過濾器從數組中選擇一個子集:{{ childrenArray | filter : 'a' }} //匹配屬性值中含有a的{{ childrenArray | filter : 4 }}? //匹配屬性值中含有4的{{ childrenArray | filter : {name : 'i'} }} //參數是對象,匹配name屬性中含有i的{{childrenArray | filter : func }}? //參數是函數 // json過濾器可以把一個js對象格式化為json字符串{{ jsonTest | json}}// 列表截取 limitTo ,支持正負數{{ childrenArray | limitTo : 2 }} // number過濾器可以為一個數字加上千位分割,像這樣,123,456,789。同時接收一個參數,可以指定float類型保留幾位小數:{{ num | number : 2 }}// 大小寫 lowercase , uppercase :{{ 'abc' | uppercase }}{{ 'Abc' | lowercase }}{{ childrenArray | orderBy : 'age' }}? ? ? //按age屬性值進行排序,若是-age,則倒序{{ childrenArray | orderBy : orderFunc }}? //按照函數的返回值進行排序{{ childrenArray | orderBy : ['age','name'] }}? //如果age相同,按照name進行排序過濾器使用方式在模塊中定義過濾器:var app = angular.module('Demo', [], angular.noop);? app.filter('map', function(){? ? var filter = function(input){? ? ? return input + '...';? ? };? ? return filter;? });然后,在模板中使用:
示例數據: {{ a | map }}
4. AngularJS Ajax$http 服務是 AngularJS 的核心服務之一,它幫助我們通過 XMLHttpRequest 對象或 JSONP 與遠程 HTTP 服務進行交流。$http 服務是這樣一個函數:它接受一個設置對象,其中指定了如何創建 HTTP 請求;它將返回一個 promise 對象,其中提供兩個方法: success 方法和 error方法。$http.get({url:"/xxx.action"}).success(function(data){? ? alert(data);}).error(function(){? ? alert("error");});$http 接受的配置項有:method 方法url 路徑params GET請求的參數data post請求的參數headers 頭transformRequest 請求預處理函數transformResponse 響應預處理函數cache 緩存timeout 超時毫秒,超時的請求會被取消withCredentials 跨域安全策略的一個東西其中的 transformRequest 和 transformResponse 及 headers 已經有定義的,如果自定義則會覆蓋默認定義對于幾個標準的 HTTP 方法,有對應的 shortcut :$http.delete(url, config)$http.get(url, config)$http.head(url, config)$http.jsonp(url, config)$http.post(url, data, config)$http.put(url, data, config)注意其中的 JSONP 方法,在實現上會在頁面中添加一個 script 標簽,然后放出一個 GET 請求。你自己定義的,匿名回調函數,會被 ng 自已給一個全局變量。在定義請求,作為 GET 參數,你可以使用 JSON_CALLBACK 這個字符串來暫時代替回調函數名,之后 ng 會為你替換成真正的函數名:var p = $http({? method: 'JSONP',? url: '/json',? params: {callback: 'JSON_CALLBACK'}});p.success(function(response, status, headers, config){? console.log(response);? $scope.name = response.name;});$http 有兩個屬性:defaults 請求的全局配置pendingRequests 當前的請求隊列狀態$http.defaults.transformRequest = function(data){? ? console.log('here'); return data;}console.log($http.pendingRequests);5. AngularJS 控制器AngularJS 應用程序被控制器控制,控制器是 JavaScript 對象,由標準的 JavaScript 對象的構造函數 創建。ng-controller 指令定義了應用程序控制器,給所在的 DOM 元素創建了一個新的 $scope 對象,并將這個 $scope 對象包含進外層 DOM 元素的 $scope 對象里。示例如下:
名:
姓:
姓名: {{fullName()}}
function personController($scope) {
$scope.person = {
firstName: "John",
lastName: "Doe",
};
$scope.fullName = function() {
var x;
x = $scope.person;
return x.firstName + " " + x.lastName;
};
}$scope 是一個把 view(一個DOM元素)連結到 controller 上的對象。在我們的 MVC 結構里,這個 $scope 將成為 model,它提供一個綁定到DOM元素(以及其子元素)上的excecution context。盡管聽起來有點復雜,但 $scope 實際上就是一個JavaScript 對象,controller 和 view 都可以訪問它,所以我們可以利用它在兩者間傳遞信息。在這個 $scope 對象里,我們既存儲數據,又存儲將要運行在view上的函數。每一個 Angular 應用都會有一個 $rootScope。這個 $rootScope 是最頂級的 scope,它對應著含有 ng-app 指令屬性的那個 DOM 元素所有scope都遵循原型繼承(prototypal inheritance),這意味著它們都能訪問父scope們。6. AngularJS 模塊AngularJS 本身的一個默認模塊叫做 ng ,它提供了 $http , $q 等等服務。服務只是模塊提供的多種機制中的一種,其它的還有命令( directive ),過濾器( filter ),及其它配置信息。然后在額外的 js 文件中有一個附加的模塊叫做 ngResource , 它提供了一個 $resource 服務。定義模塊定義模塊的方法是使用 angular.module 。調用時聲明了對其它模塊的依賴,并定義了“初始化”函數。? var my_module = angular.module('MyModule', [], function(){? ? ? console.log('here');? });這段代碼定義了一個叫做 MyModule 的模塊, my_module 這個引用可以在接下來做其它的一些事,比如定義服務。定義服務ng的服務是這樣定義的:Angular services are singletons objects or functions that carry out specific tasks common to web apps.它是一個單例對象或函數,對外提供特定的功能。首先是一個單例,即無論這個服務被注入到任何地方,對象始終只有一個實例。其次這與我們自己定義一個function然后在其他地方調用不同,因為服務被定義在一個模塊中,所以其使用范圍是可以被我們管理的。ng的避免全局變量污染意識非常強。ng提供了很多內置的服務,可以到API中查看 http://docs.angularjs.org/api/ 。如同指令一樣,系統內置的服務以$開頭,我們也可以自己定義一個服務。在這里呢,就要先介紹一下叫 provider 的東西。簡單來說, provider 是被 注入控制器 使用的一個對象,注入機制通過調用一個 provider 的 $get() 方法,把得到的東西作為參數進行相關調用(比如把得到的服務作為一個 Controller 的參數)。在這里 服務 的概念就比較不明確,對使用而言,服務僅指 $get() 方法返回的東西,但是在整體機制上,服務又要指提供了 $get() 方法的整個對象。? //這是一個provider? var pp = function(){? ? this.$get = function(){? ? ? return {'haha': '123'};? ? }? }? //我在模塊的初始化過程當中, 定義了一個叫 PP 的服務? var app = angular.module('Demo', [], function($provide){? ? $provide.provider('PP', pp);? });? //PP服務實際上就是 pp 這個 provider 的 $get() 方法返回的東西? app.controller('TestCtrl',? ? function($scope, PP){? ? ? console.log(PP);? ? }? );ng 還有相關的 shortcut, 第一個是 factory 方法 ,由 $provide 提供, module 的 factory 是一個引用,作用一樣。這個方法直接把一個函數當成是一個對象的 $get() 方法,這樣你就不用顯式地定義一個 provider 了:var app = angular.module('Demo', [], function($provide){? ? $provide.factory('PP', function(){? ? ? ? return {'hello': '123'};? ? });});app.controller('TestCtrl', function($scope, PP){ console.log(PP) });在 module 中使用:var app = angular.module('Demo', [], function(){ });app.factory('PP', function(){return {'abc': '123'}});app.controller('TestCtrl', function($scope, PP){ console.log(PP) });第二個是 service 方法,也是由 $provide 提供, module 中有對它的同名引用。 service 和 factory 的區別在于,前者是要求提供一個“構造方法”,后者是要求提供 $get() 方法。意思就是,前者一定是得到一個 object ,后者可以是一個數字或字符串。它們的關系大概是:var app = angular.module('Demo', [], function(){ });app.service = function(name, constructor){? ? app.factory(name, function(){? ? ? return (new constructor());? ? });}service 方法的使用就很簡單了:var app = angular.module('Demo', [], function(){ });app.service('PP', function(){? ? this.abc = '123';});app.controller('TestCtrl', function($scope, PP){ console.log(PP) });引入模塊并使用服務結合上面的 定義模塊 和 定義服務 ,我們可以方便地組織自己的額外代碼:// 定義服務angular.module('MyModule', [], function($provide){? ? $provide.factory('S1', function(){? ? ? return 'I am S1';? ? });? ? $provide.factory('S2', function(){? ? ? return {see: function(){return 'I am S2'}}? ? });});// 調用服務var app = angular.module('Demo', ['MyModule'], angular.noop);app.controller('TestCtrl', function($scope, S1, S2){? ? console.log(S1)? ? console.log(S2.see())});7. 附加模塊 ngResourcengResource 這個是 ng 官方提供的一個附加模塊。 附加 的意思就是,如果你打算用它,那么你需要引入一人單獨的 js 文件,然后在聲明“根模塊”時注明依賴的 ngResource 模塊,接著就可以使用它提供的 $resource 服務了。$resource 服務主要是包裝了 AJAX 的調用,使用 $resource 需要先定義“資源”,也就是先定義一些 HTTP 請求。TODO8. AngularJS 路由ng的路由(ngRoute)是一個單獨的模塊,包含以下內容:服務 $routeProvider 用來定義一個路由表,即地址欄與視圖模板的映射服務 $routeParams 保存了地址欄中的參數,例如 {id : 1, name : 'tom'}服務 $route 完成路由匹配,并且提供路由相關的屬性訪問及事件,如訪問當前路由對應的 controller指令 ngView 用來在主視圖中指定加載子視圖的區域定義路由第一步:引入文件和依賴ngRoute 也是一個附件模塊,故需要在頁面上引入 angular-route.min.js 并在模塊中注入對 ngRoute 的依賴,如下:var app = angular.module('MyApp', ['ngRoute']);第二步:定義路由表$routeProvider 提供了定義路由表的服務,它有兩個核心方法: when(path,route) 和 otherwise(params) ,先看一下核心中的核心 when(path,route)方法。when(path,route) 方法接收兩個參數:path 是一個 string 類型,表示該條路由規則所匹配的路徑,它將與地址欄的內容($location.path)值進行匹配。如果需要匹配參數,可以在 path 中使用冒號加名稱的方式,如:path為 /show/:name ,如果地址欄是 /show/tom ,那么參數 name 和所對應的值 tom 便會被保存在 $routeParams 中,像這樣: {name : tom} 。我們也可以用 * 進行模糊匹配,如: /show*/:name 將匹配 /showInfo/tom 。route 參數是一個 object,用來指定當 path 匹配后所需的一系列配置項,包括以下內容:controller function 或 string 類型。在當前模板上執行的 controller 函數,生成新的 scope;controllerAs string 類型,為 controller 指定別名;template string 或 function 類型,視圖所用的模板,這部分內容將被 ngView 引用;templateUrl string 或 function 類型,當視圖模板為單獨的 html 文件或是使用了定義模板時使用;resolve 指定當前 controller 所依賴的其他模塊;redirectTo 重定向的地址。第三步:在主視圖模板中指定加載子視圖的位置只需在模板中簡單的使用此 ngView 指令: