javascript
AngularJS学习笔记(一)
前言
幾個(gè)月之前了解過一點(diǎn)Angular,主要是通過phonecat應(yīng)用程序了解一些入門東西,但是當(dāng)被問及什么是Angular或者你對Angular的理解時(shí),只記得一個(gè)MVVM雙向數(shù)據(jù)綁定,顯然這是不能令人滿意的。現(xiàn)在重新來過吧。
ps:該文檔只是見證自己學(xué)習(xí)Angular的過程。所用版本為1.4.3。另外向大家推薦個(gè)windows下各 API離線查找工具Velocity,官網(wǎng):http://velocity.silverlakesoftware.com/,真的不是一般地好用。
AngularJS簡介
AngularJS是一個(gè)為動態(tài)WEB應(yīng)用設(shè)計(jì)的結(jié)構(gòu)框架,創(chuàng)新點(diǎn)在于,利用數(shù)據(jù)綁定和依賴注入,使你不用再寫大量的代碼。AngularJS的一些出眾之處在于:
- 構(gòu)建一個(gè)CRUD應(yīng)用可能用到的全部內(nèi)容包括:數(shù)據(jù)綁定、基本模板標(biāo)識符、表單驗(yàn)證、路由、深度鏈接、組件重用、依賴注入
- 測試方面包括:單元測試、端到端測試、模擬和自動化則是框架
- 具有目錄布局和測試腳本的種子應(yīng)用作為起點(diǎn)
而Angular信奉的是,當(dāng)組建視圖同時(shí)又要寫軟件邏輯時(shí),聲明式的代碼會比命令式的代碼好的多。
基本概念
首先舉個(gè)例子:
<!doctype html> <html lang="en" ng-app="myApp"> <head><meta charset="UTF-8"><title>myApp</title><style>#test {width: 100px;height: 100px;background-color: red;border: 1px solid #ccc;}</style><script src="js/jquery-1.7.1.js"></script><script src="js/angular.min.js"></script> </head> <body ng-controller="myCtrl"><div id="test" ng-click="click()">Come ON!</div><p>{{width}} * {{height}}</p><p>Width: <input type="text" ng-model="width"/></p><p>Height: <input type="text" ng-model="height"/></p><script>"use strict";var myApp = angular.module("myApp", []);myApp.controller('myCtrl', ['$scope', function($scope) {var oDiv = angular.element('#test');$scope.width = oDiv.width();$scope.height = oDiv.height();$scope.click = function() {$scope.width = parseInt($scope.width) + 10;$scope.height = parseInt($scope.height) + 10;};$scope.$watch('width', function(to, from) {oDiv.width(to);});$scope.$watch('height', function(to, from) {oDiv.height(to);});}]);</script> </body> </html>從代碼中可以看出,在HTML中引入了一些以ng開頭的標(biāo)記,這些就是angular(一下簡稱ng)聲明式的代碼。
- 使用ng-app聲明ng的初始化工作,同時(shí)定義了ng應(yīng)用的作用域,ng的初始化一般綁定在DOMContentLoaded事件中,可以使用angular.bootstap(element,modules,config);手動引導(dǎo)ng應(yīng)用程序。
- ng-controller聲明控制器,控制器里可以寫相應(yīng)的代碼邏輯,修改相應(yīng)的$scope,進(jìn)行model到view的數(shù)據(jù)綁定工作。
- ng-click綁定click事件,事件在controller中聲明,綁定到$scope.
- ng模板解析:默認(rèn)使用{{}}
- ng-model:ng的雙向數(shù)據(jù)綁定聲明
依賴注入
ng通過在函數(shù)參數(shù)中做手腳來完成“依賴聲明”的功能。['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {}]像AMD聲明一樣,該函數(shù)依賴于$scope,dep1,dep2,然后依次作為參數(shù)傳遞進(jìn)去。也可以使用另外一種聲明方式,利用ng中的函數(shù)隱藏屬性$inject(不推薦):
var MyController = function($scope, greeter) {} MyController.$inject = ['$scope', 'greeter']; someModule.controller('MyController', MyController);在處理時(shí),ng通過函數(shù)對象的toString()方法將該函數(shù)定義的代碼轉(zhuǎn)為字符串表現(xiàn)形式,然后利用正則表達(dá)式過濾出相應(yīng)的參數(shù),通過參數(shù)名獲取資源,最后把資源作為參數(shù)調(diào)用定義的函數(shù)。
因此最好采用上述兩種方法來顯示聲明所需的依賴,防止代碼壓縮過程中壓縮相應(yīng)的函數(shù)參數(shù)而報(bào)錯(cuò)。
作用域
每個(gè)ng應(yīng)用都有一個(gè)根作用域($rootScope),有多個(gè)子作用域。因?yàn)橐恍┲噶顣暶餍碌淖幼饔糜?#xff0c;這些作用域的結(jié)構(gòu)關(guān)系和其綁定到相應(yīng)的DOM結(jié)構(gòu)是對應(yīng)的。
屬性查找:當(dāng)ng查找某個(gè)模板中的某個(gè)數(shù)據(jù)時(shí),會按照作用域鏈一直向上查找,直至找到或查至根作用域$rootrScope為至(獨(dú)立作用域除外)。
事件冒泡:我們可以在scopes上模擬DOM事件類型的事件冒泡,該事件可以被廣播到子作用域或者觸發(fā)到父作用域。
<div ng-controller="EventController">Root scope <tt>MyEvent</tt> count: {{count}}<ul><li ng-repeat="i in [1]" ng-controller="EventController"><button ng-click="$emit('MyEvent')">$emit('MyEvent')</button><button ng-click="$broadcast('MyEvent')">$broadcast('MyEvent')</button><br>Middle scope <tt>MyEvent</tt> count: {{count}}<ul><li ng-repeat="item in [1, 2]" ng-controller="EventController">Leaf scope <tt>MyEvent</tt> count: {{count}}</li></ul></li></ul> </div><script>angular.module('myApp', []).controller('EventController', ['$scope', function($scope) {$scope.count = 0;$scope.$on('MyEvent', function() {$scope.count++;});}]);</script>另外,我們還可以調(diào)用$watch()檢測某個(gè)屬性改變。
模板與數(shù)據(jù)綁定
ng中的主要特點(diǎn)之一就是雙向數(shù)據(jù)綁定。
數(shù)據(jù)->模板:
可以直接使用ng的默認(rèn)模板標(biāo)記{{name}},則可以直接綁定一個(gè)作用域內(nèi)的變量。當(dāng)然也可以更改使用自定義的標(biāo)記//name//
<script>myApp.config(function($interpolateProvider) {$interpolateProvider.startSymbol('//');$interpolateProvider.endSymbol('//');}); </script>模板:
ng有自己的一套強(qiáng)大的模板命令:
1.ng-include直接引入模板內(nèi)容
<div ng-include="'template.html'"></div>
ng-include內(nèi)容必須是字符串,需多加個(gè)引號。
template.html主要有兩種定義方式:
(1)script標(biāo)簽中定義:type屬性值為“text/ng-template”,id為ng-include屬性值
(2)外部html文件中定義:該html文件名為ng-include的屬性值
Content of template.html2.內(nèi)容控制:
(1)ng-cloak
該指令綁定內(nèi)容不顯示,直到ng解析相關(guān)指令后才顯示解析后的內(nèi)容,避免相關(guān)內(nèi)容解析前后出現(xiàn)跳轉(zhuǎn)現(xiàn)象。
(2)ng-show/ng-hide
根據(jù)表達(dá)式的值來改變綁定該命令的DOM的display屬性,相關(guān)CSS類已經(jīng)在ng文件中提前定義,且使用了!important提升權(quán)重。
(3)ng-if
不同于ng-show改變DOM的display屬性來顯示隱藏節(jié)點(diǎn),ng-if根據(jù)表達(dá)式的布爾值判斷:false則從文檔中移除該DOM節(jié)點(diǎn),true則向文檔中添加該DOM節(jié)點(diǎn)。
(4)ng-switch
根據(jù)值的匹配情況來顯示相應(yīng)的節(jié)點(diǎn):
ng-init直接在模板中進(jìn)行賦值,與作用域無關(guān)。
(5)ng-repeat
遍歷對象或數(shù)組:
額外變量:
$index 當(dāng)前索引
$first 是否為首元素
$middle 是否為中間元素
$last 是否為尾元素
$odd 當(dāng)前索引是否為奇數(shù)
$even 當(dāng)前索引是否為偶數(shù)
遍歷對象使用(key, value) in obj.
另外,默認(rèn)待遍歷的數(shù)組中不能有重復(fù)值,因?yàn)閿?shù)組元素與相應(yīng)的DOM元素是一對一的關(guān)系。如需要使用:
(6)其它
- ng-src src屬性
- ng-href href屬性
- ng-checked 選中狀態(tài)
- ng-selected 被選擇狀態(tài)
- ng-disabled 禁用狀態(tài)
- ng-multiple 多選狀態(tài)
- ng-readonly 只讀狀態(tài)
3.樣式
(1)ng-style
使用對象字面量的形式來賦值:
(2)ng-class
直接通過字符串綁定CSS中預(yù)定義的類
4.事件綁定:
模板中的事件綁定預(yù)定義了一些常用的事件綁定指令,可以直接傳遞相關(guān)的處理程序且直觀地在DOM中聲明。
- ng-blur
- ng-change
- ng-click
- ng-dblclick
- ng-focus
- ng-keydown
- ng-keypress
- ng-keyup
- ng-mousedown
- ng-mouseenter
- ng-mouseleave
- ng-mousemove
- ng-mouseover
- ng-mouseup
使用$event可以給相應(yīng)的事件處理函數(shù)傳遞事件對象本身
5.表單
HTML中form是一個(gè)核心控件,是網(wǎng)頁與用戶進(jìn)行交流的主要方式之一。而ng對form進(jìn)行了封裝”ng-form”,區(qū)別是HTML中的form不能嵌套,而ng-form可以嵌套。而ng-form的目的就是為了統(tǒng)一控制,而不是為了取代form標(biāo)簽。
form中的一些控件可以預(yù)先通過ng-controller中的$scope綁定一些狀態(tài)。
<!doctype html> <html lang="en" ng-app="myApp"> <head><meta charset="UTF-8"><title>Document</title><script src="js/angular.min.js"></script> </head> <script>angular.module('myApp', []).controller('FormController', ['$scope', function($scope) {$scope.userType = 'guest';}]); </script> <style>.my-form {-webkit-transition:all linear 0.5s;transition:all linear 0.5s;background: transparent;}.my-form.ng-invalid {background: red;} </style> <body> <form name="myForm" ng-controller="FormController" class="my-form">userType: <input name="input" ng-model="userType" required ><span class="error" ng-show="myForm.input.$error.required">Required!</span><br>age: <input name="input_b" ng-model="age" required pattern="\d+"><span class="error" ng-show="myForm.input_b.$error.required">Required!</span><span class="error" ng-show="myForm.input_b.$error.pattern">Pattern!</span><br><code>userType = {{userType}}</code><br><code>myForm.input.$valid = {{myForm.input.$valid}}</code><br><code>myForm.input.$error = {{myForm.input.$error}}</code><br><code>myForm.$valid = {{myForm.$valid}}</code><br><code>myForm.$error.required = {{!!myForm.$error.required}}</code><br> </form> </body> </html>ng給form提前定義了一些CSS類:
- ng-valid 當(dāng)表單驗(yàn)證全部通過時(shí)使用
- ng-invalid 表單中有未通過驗(yàn)證的控件時(shí)使用
- ng-pristine 當(dāng)表單為被修改之前使用
- ng-dirty 當(dāng)表單被修改之后使用
- ng-submitted 當(dāng)表單被提交之后使用
form對象有一些屬性:
- $pristine 表單是否未被動過
- $dirty 表單是否被動過
- $valid 表單是否通過驗(yàn)證
- $invalid 表單是否未通過驗(yàn)證
- $error 表單的錯(cuò)誤對象
其中$error是一個(gè)hash對象,引用表單控件中未通過驗(yàn)證的鍵值對。屬性是驗(yàn)證失敗信息,值是對應(yīng)的實(shí)例列表。另外,該失敗對象是按一定的驗(yàn)證邏輯所取,例如上例中的age輸入框,先判定required,在判定pattern。$error對象可能的屬性有:email/max/maxlength/min/minlength/number/pattern/required/url/date/time/week/month.
同時(shí),我們也能在form中的具體某個(gè)input框中查看相應(yīng)的錯(cuò)誤,格式為formName.inputName.$error.但是,input控件的相關(guān)屬性是ng-required/ng-pattern等,經(jīng)測試發(fā)現(xiàn),僅ng-maxlength,ng-max,ng-min與HTML5中相關(guān)屬性有區(qū)別:ng-maxlength=’12’可以輸入超過12個(gè)字符,但超過相關(guān)屬性為true,而maxlength則最多只能輸入12個(gè)字符,超過默認(rèn)丟棄,相關(guān)錯(cuò)誤屬性永不為true.
(1)checkbox/radio
可以為checkbox分別綁定ng-true-value/ng-false-value的值,為radio綁定value值。而這些值與視圖中的相關(guān)控件是否選中相對應(yīng)。
(2)textarea
包含input框中相應(yīng)屬性,僅多了ng-trim指令。
(3)select
select控件中,有個(gè)用于呈現(xiàn)下拉選項(xiàng)的指令ng-options主要用于select模板中綁定的是非字符串。主要用法見下例:
通常情況下,ng-repeat也可用在option元素中,但ng-repeat會為每個(gè)遍歷的實(shí)例創(chuàng)造一個(gè)新的作用域,而使用ng-options則具有節(jié)省內(nèi)存,響應(yīng)更快捷的優(yōu)點(diǎn)。
模板->數(shù)據(jù):
ng中模板到數(shù)據(jù)的綁定主要是通過ng-model來實(shí)現(xiàn)。
<p>hello {{name || "World"}}!</p> <hr/> <input type="text" ng-model="name"/>當(dāng)我們在input框中輸入內(nèi)容,會發(fā)現(xiàn)模板中內(nèi)容也相應(yīng)改變。實(shí)際上,ng中的雙向數(shù)據(jù)綁定主要是通過ng-model來實(shí)現(xiàn)。
過濾
ng默認(rèn)提供了一些可以直接使用的過濾指令
- currency 貨幣過濾指令
- date 時(shí)間過濾指令
- filter 數(shù)組過濾指令
- json 將js對象轉(zhuǎn)換為json字符串
- limitTo 截取字符串/數(shù)組/數(shù)字的一部分
- lowercase 字符串轉(zhuǎn)小寫
- number 格式化數(shù)字
- orderBy 數(shù)組排序
- uppercase 字符串轉(zhuǎn)大寫
- linky 找出文本輸入中的連接然后格式化
模板中使用
我們可以在模板中使用過濾命令,使用方法類似與linux系統(tǒng)中的管道命令{{expression | filter1:arg1:arg2:... | filter2:arg}}即我們可以在一個(gè)語句后面使用多個(gè)過濾命令,依次用”|”分割開即可,也可以在一個(gè)過濾命令后面?zhèn)鬟f多個(gè)參數(shù),依次用“:”分割開即可。
<span>{{1437272917693 | date:"MM/dd/yyyy 'at' h:mma"}}</span><br> <span>{{ ["AAAAA","AAAA","AAA","AA","A","BBB","BB"] | filter:'A' | limitTo: 2 }}</span><br>JS中使用
JS中使用過濾命令有兩種方式:
(1)<filterName>Filter方式:
在依賴聲明中明確聲明需要使用filterName的過濾指令,然后就可以在內(nèi)部向該指令函數(shù)傳遞參數(shù),返回處理后的數(shù)據(jù):
(2)$filter方式
依賴聲明中引入$filter,然后我們就可以在內(nèi)部向該函數(shù)傳入我們想要使用的過濾指令名,返回對應(yīng)的過濾指令函數(shù)。較方式1簡單:
自定義過濾命令
如果感覺ng默認(rèn)提供的幾種過濾指令滿足不了需求,我們可以自定義指令。通過你的module中的filter工廠函數(shù)就可以自定義一個(gè)新的指令。
angular.module('myApp', []).filter('reverse', function() {return function(input, uppercase) {input = input || '';var out = "";for (var i = 0; i < input.length; i++) {out = input.charAt(i) + out;}// 可傳入?yún)?shù)uppercaseif (uppercase) {out = out.toUpperCase();}return out;};})向filter工廠函數(shù)傳入命令名,初始化函數(shù),返回一個(gè)過濾函數(shù),過濾函數(shù)第一個(gè)參數(shù)是待過濾的內(nèi)容,其余參數(shù)依次輸入。僅當(dāng)該過濾指令的輸入內(nèi)容改變時(shí),ng才會執(zhí)行該指令。
另外,自定義的過濾函數(shù)應(yīng)該全部是無狀態(tài)的,那些有狀態(tài)的指令無法被ng優(yōu)化,經(jīng)常導(dǎo)致表現(xiàn)問題。而如果真的需要維持狀態(tài)的過濾命令,可指定該過濾函數(shù)的$stateful屬性,這樣每次模板中內(nèi)容改變該過濾函數(shù)都會執(zhí)行一次。
另外,自定義的過濾函數(shù)只能在模板中使用。
AJAX
與其它框架一樣,ng也提供了類似的一套AJAX封裝,內(nèi)部通過XMLHttpRequest對象或JSONP方式。
$HTTP
$HTTP提供基本的操作服務(wù),傳入一個(gè)config配置對象,設(shè)置一些參數(shù),返回一個(gè)可以注冊成功、失敗回調(diào)函數(shù)的promise對象。$http常用的配置有:
- method 請求方法
- url 請求路徑
- params GET請求的參數(shù)
- data 請求報(bào)文(POST請求的參數(shù))
- headers 定義請求報(bào)頭
- cache GET請求的緩存
- timeout 過期時(shí)間
- responseType 響應(yīng)類型
另外對于一些請求方式,有一些簡寫:
- $http.get(url, [config])
- $http.delete(url, [config])
- $http.head(url, [config])
- $http.jsonp(url, [config])
- $http.post(url, data, [config])
- $http.put(url, data, [config])
$http屬性:
- pendingRequests 當(dāng)前請求隊(duì)列狀態(tài),主要用于測試
- defaults 請求的全局配置
異步回調(diào)
ng的異步回調(diào)函數(shù)服務(wù)$q為AJAX的異步回調(diào)提供服務(wù)。
(1)$q用法
- $q(resolveFn, errorFn) 注冊并返回一個(gè)promise對象
- $q.defer() 返回一個(gè)deferred實(shí)例
- $q.reject(reason) 包裝一個(gè)錯(cuò)誤
- $q.when(value) 返回一個(gè)promise對象
- $q.resolve(value) 與when方法一樣,為了與ES6保持一致性
- $q.all(promises) 將多個(gè)promise對象合并成一個(gè)promise對象
(2)deferred對象:通過$q.defer()構(gòu)建
- resolve(value) 成功回調(diào)
- reject(reason) 失敗回調(diào)
- notify(value) 更新promise的執(zhí)行狀態(tài)
- promise屬性 返回一個(gè)promise對象
(3)promise
- then(successCallback, errorCallback, notifyCallback) 分別注冊成功,失敗,通知的回調(diào)函數(shù)
- catch(errorCallback) 相當(dāng)于then(null, errorCallback) 注冊失敗回調(diào)函數(shù)
- finally(callback, notifyCallback)
其它部分,明天繼續(xù)。。。
參考內(nèi)容
http://www.zouyesheng.com/angular.html
http://www.cnblogs.com/lcllao/archive/2012/10/18/2728787.html
轉(zhuǎn)載于:https://www.cnblogs.com/qingguo/p/5686290.html
總結(jié)
以上是生活随笔為你收集整理的AngularJS学习笔记(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么了解泰山的历史故事?
- 下一篇: 怎么在泰山保护自身安全?