《AngularJS高級程序設計》學習筆記
——持續更新中
一、AngularJS應用剖析
AngularJS存在一些最主要的構件,如模型,視圖和控制器。但AngularJS中也有許多其他可供靈活使用的部件,包括模塊,指令,過濾器,工廠和服務。
一 . 1 依賴注入
沒有依賴注入(dependencies injector),就不得不以某種方式找到自己所需要的組件,很可能得使用到全局變量。雖然這樣子也能工作,但是不如AngularJS的依賴注入來的簡單。依賴注入,可以通過讓某個組件的工廠函數的參數上聲明依賴來實現,這個函數使用參數來提出需求: "Hey! AngularJS兄弟,我需要這樣子的一個構件!"
app.controller("HelloController", function($scope, $timeout){ //hey, AngularJS 我需要$scope,和$timeout
//為了我能正常運行,麻煩你先把這兩個構件幫我准備一下吧!
})
依賴注入的主要好處是AngularJS輔助管理組件,並在需要時提供給相應的函數。依賴注入還為測試帶來好處。
一 . 2 工人和工人函數
簡單的概念:AngularJS在需要建立構件時將調用工廠函數,當需要使用該構件時就會調用工人。相當於,工廠函數是模具,工人則是通過這個模具制造出來的實體。工廠函數負責創建那些來執行工作的對象,工廠函數往往會返回一個工人函數。下面的這個例子中,第一個function便是工廠函數,return的內容則是一個工人(對象實例)。
app.directive("Hello", function(){ return function(scope, ele, attrs){ //....
} })
一 . 3 . 1 使用模塊工作
隨着應用程序隨着時間的推移會變得復雜,因此我們需要使用模塊來使我們對程序進行更有效、編輯的管理測試和工作。模塊具有三種主要角色:1. 將一個AngularJS程序與HTML文檔中的一部分進行關聯(ng-app作用范圍)。2. 幫助我們組織AngularJS應用程序中的代碼和組件
var app = angular.module("myApp", ["app.Controllers", "app.Filters", "app.Servers", "app.Directive"]);
...
其中,這些依賴並不是必須按照某種特定的順序定義的。但是AngularJS會保證這些具有依賴的模塊(此處的app模塊)會首先調用其(app模塊)所依賴("app.Controllers", "app.Filters", "app.Servers", "app.Directive")的回調函數。相當於,有個哥們想自己組裝一部四驅車,那他會把輪子,車身,電池什么的先給准備好。
一 . 3. 2 config與run
config方法會接受一個函數,這個函數會在相應模塊被調用之后被調用。config方法常常會通過注入其他服務的值的方式來配置模塊
app.config(function($httpProvider){
//...
})
run方法也會接受一個函數,但是該函數之會在所有模塊都加載完以及解析完它們的依賴之后才會被調用
app.run(function($rootScope){
//...
])
執行順序——一個例子
App.Servives模塊的config回調函數
App模塊的config回調函數
App.Servives模塊的run回調函數
App模塊的run回調函數
二、AngularJS指令系統
二、1 數據綁定類指令
數據綁定類指令是負責執行數據綁定的,數據綁定是使用模型中的值並將它插入到HTML文檔中。
1. ng-bind-template 大家都知道ng-bind會替換它被用到的元素內容,而且ng-bind受限於只能處理單個數據綁定的表達式 <span ng-bind="bool"></span,
當需要進行創造多個數據綁定便可以使用靈活的ng-bind-template
<div ng-bind-template="First: {{my.mum}} and {{my.dad}}">
2. ng-non-bindable 阻止內聯數據綁定
AngularJS不是說唯一使用{{ }}符號的JavaScript包,因此如果同時使用多個庫可能會遇到問題,或者我僅僅是想輸出"{{ }}"這個符合。AngularJS在請求綁定到一個不存在的模型屬性時不會報錯。例如 AngularJS uses {{ and }} characters for tempalte 會被替換成 AngularJS uses characters for tempalte ,因此使用ng-non-bindable可以為我們解決這個問題,以下實例會輸出 AngularJS uses {{ and }} characters for tempalte
<div ng-non-bindable> AngularJS uses {{ and }} characters for tempalte </div>
二、2 模板類指令
1. ng-repeat
<li ng-repeat="(key, value) in item"> {{key}} = {{value}} </li>
當遍歷目標是對象時, key為當前屬性名,value為對象屬性的值。而當遍歷目標是集合(如一個數組)時, key為當前的遍歷下標(從0開始),value為集合的值
ng-repeat的內置變量
$index: 返回當前的遍歷下標
$first/$last: 若當前對象時遍歷集合的第一/最后一個元素,則返回true
$even/$odd: 若當前對象時遍歷集合的第偶數個/第奇數個元素,則返回true
$middle: 若當前對象時遍歷集合的中間元素(不是第一或者最后一個元素),則返回true
ng-repeat + ng-if
我們無法再ng-repeat指令所應用到的同一個元素上使用ng-if <li ng-repeat="item in Objs" ng-if="item.exist">{{item.name}}</li> 這樣子會報錯。我們應該先把數據通過filter服務整合出來后,再用ng-repeat遍歷訪問 <li ng-repeat="item in Objs | filter: {exist: 'true'}" >{{item.name}}</li>
2. ng-include
<ng-include src=" 'template.html' "></ng-include> 請注意,此處有坑,雙引號里面還有一個單引號。
ng-include的配置參數
src: 指定加載內容的URL;onload: 指定一內容被加載后調用的計算表達式;autoscroll: 指定內容被加載時,是否滾動到這部分視圖所在區域(注:小鵬我在實驗時發現這個配置參數並沒有運行..不知道是不是哪里引用錯誤了)
ng-include VS ng-switch
ng-switch適合用於復雜度不高,內容較小的時候使用。ng-include適用於復雜性較大,內容較多的頁面,但首次加載時,AngularJS會使用ajax來請求模板,因此會有延遲。
二、3 事件類指令
我們可以通過分辨發事件對象中event.type屬性,來處理在發生同一元素上不同的事件<li ng-repeat="item in items" ng-mouseenter="handle($event)" ng-mouseleave="handle($event)"> 。但是應該注意:AngularJS為事件指令所用的事件名稱和底層事件的type屬性之間存在不匹配的情況。例如 ng-mouseenter="handle($event)" 但他的 event.type == "mouseover" 。因此,我們在處理此類情況情況時,應當先確認事件的底層名稱。
$scope.handle(event){
console.log(event.type)
}
二、4 布爾屬性類指令
ng-check 管理checked屬性(input="checkbox")
ng-diabled 管理disabled屬性(input與button元素)
ng-open 管理open屬性(detail元素)
ng-readonly 管理readonly屬性(input元素)
ng-selected 管理selectes屬性(option元素)
資料參考:
《AngularJS高級程序設計》