Angular.JS notes
內置指令
- 在JS中使用run的方法來訪問$rootScope.
- 在Angular中,將模型對象的某個屬性設置爲字符串,它會通過引用進行共享,因此在子
scope中修改屬性也會修改父 scope中的這個屬性。 - ng-if同no-show和ng-hide指令最本質的區別是,它不是通過CSS顯示或隱藏DOM節點,而是真正生成或移除節點。
ng-repeat用來遍歷一個集合或爲集合中的每個元素生成一個模板實例.
- $index:遍歷的進度(0…length-1)。
- $first:當元素是遍歷的第一個時值爲true。
- $middle:當元素處於第一個和最後元素之間時值爲true。
- $last:當元素是遍歷的最後一個時值爲true。
- $even:當$index值是偶數時值爲true。
- $odd:當$index值是奇數時值爲true。
ng-init指令用來在指令被調用時設置內部作用域的初始狀態。
{{ }}語法是AngularJS內置的模板語法,它會在內部 $scope和視圖之間創建綁定。基於這個綁定,只要$scope發生變化,視圖就會隨之自動更新。事實上它也是指令,雖然看起來並不像,實際上它是ng-bind的簡略形式.
在屏幕可視的區域內使用{{ }}會導致頁面加載時未渲染的元素髮生閃爍,用ng-bind可以避免這個問題。除使用ng-bind來避免未渲染元素閃爍,還可以在含有{{ }}的元素上使用ng-cloak指令
ng-cloak指令會將內部元素隱藏,直到路由調用對應的頁面時才顯示出來。
- ng-bind-template: 同ng-bind指令類似,ng-bind-template用來在視圖中綁定多個表達式。
<div
ng-bind-template="{{message}}{{name}}">
</div> - ng-model指令用來將input、select、textarea或自定義表單控件同包含它們的作用域的屬性進行綁定。
- ng-show和ng-hide根據所給表達式的值來顯示或隱藏HTML元素
<div ng-show="2 + 2 == 5">
2 + 2 isn't 5, don't show
</div>
<div ng-show="2 + 2 == 4">
2 + 2 is 4, do show
</div>
- ng-change這個指令會在表單輸入發生變化時計算給定表達式的值,因爲要處理表單輸入,這個指令要和ngModel聯合起來使用
- ng-form用來在一個表單內部嵌套另一個表單
- ng-click用來指定一個元素被點擊時調用的方法或表達式。
- ng-select用來將數據同HTML的
<select>
元素進行綁定。這個指令可以和ng-model以及ng-options指令一同使用,構建精細且表現優良的動態表單。ng-options的值可以是一個內涵表達式(comprehension expression),簡單來說就是它可以接受一個數組或對象,並對它們進行循環,將內部的內容提供給select標籤內部的選項 - ng-submit用來將表達式同onsubmit事件進行綁定。這個指令同時會阻止默認行爲(發送請求並重新加載頁面),除非表單不含有action屬性。
- 使用ng-class 動態設置元素的類,方法是綁定一個代表所有需要添加的類的表達式
自定義指令
directive()這個方法是用來定義指令
directive() 方法可以接受兩個參數:
name(字符串)
指令的名字,用來在視圖中引用特定的指令。
factory_function (函數)
這個函數返回一個對象,其中定義了指令的全部行爲。restrict是一個可選的參數。它告訴AngularJS這個指令在DOM中可以何種形式被聲明。默認AngularJS認爲restrict的值是A,即以屬性的形式來進行聲明。
可選值如下:
E(元素)
<my-directive></my-directive>
A(屬性,默認值)
<div my-directive="expression"></div>
C(類名)
<div class="my-directive:expression;"></div>
M(註釋)
<--directive:my-directive expression-->
terminal是一個布爾型參數,可以被設置爲true或false。這個參數用來告訴AngularJS停止運行當前元素上比本指令優先級低的指令。但同當前指令優先級相同的指令還是會被執行.
- template參數是可選的,必須被設置爲以下兩種形式之一
- 一段HTML文字, 如果模板字符串中含有多個DOM元素,或者只由一個單獨的文本節點構成,那它必須被包含在一個父元素內。換句話說,必須存在一個根DOM元素
- 一個可以接受兩個參數的函數,參數爲tElement和tAttrs,並返回一個代表模板的字符串。tElement和tAttrs中的t代表template,是相對於instance的.
- templateUrl(字符串或函數):
1,一個代表外部HTML文件路徑的字符串;
2,一個可以接受兩個參數的函數,參數爲tElement和tAttrs,並返回一個外部HTML文件路徑的字符串。 - replace是一個可選參數,如果設置了這個參數,值必須爲true,因爲默認值爲false。默認值意味着模板會被當作子元素插入到調用此指令的元素內部
指令作用域
$rootScope這個特殊的對象會在DOM中聲明ng-app時被創建, 創建具有隔離作用域的指令需要將scope屬性設置爲一個空對象{}。如果這樣做了,指令的模板就無法訪問外部作用域了
scope參數是可選的,可以被設置爲true或一個對象。默認值是false。當scope設置爲true時,會從父作用域繼承並創建一個新的作用域對象。
- 綁定策略
本地作用域屬性:
使用@符號將本地作用域同DOM屬性的值進行綁定。指令內部作用域可以使用外部作用域的變量:@(or @attr)
雙向綁定:通過=可以將本地作用域上的屬性同父級作用域上的屬性進行雙向的數據綁定。就像普通的數據綁定一樣,本地屬性會反映出父數據模型中所發生的改變。= (or =attr)。
路由
angular.route VS ui.router
Angular.route模塊路由:
ng-view是由ngRoute模塊提供的一個特殊指令,它的獨特作用是在HTML中給$route對應的視圖內容佔位。ng-view是一個優先級爲1000的終極指令.
ng-View指令遵循以下規則:
1. 每次觸發$routeChangeSuccess事件,視圖都會更新。
2. 如果某個模板同當前的路由相關聯:
- 創建一個新的作用域;
- 移除上一個視圖,同時上一個作用域也會被清除;
- 將新的作用域同當前模板關聯在一起;
- 如果路由中有相關的定義,那麼就把對應的控制器同當前作用域關聯起來;
- 觸發$viewContentLoaded事件;
使用When方法進行路由:這個方法可以接受兩個參數(when(path,
route))。
第一個參數是路由路徑,這個路徑會與$location.path進行匹配,$location.path也就是當前URL的路徑。
第二個參數是配置對象,決定了當第一個參數中的路由能夠匹配時具體做些什麼。配置對象中可以進行設置的屬性包括controller、template、templateURL、resolve、redirectTo和reloadOnSearch。
angular.module('myApp', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/home.html',
controller: 'HomeController'
})
.when('/login', {
templateUrl: 'views/login.html',
controller: 'LoginController'
})
.when('/dashboard', {
templateUrl: 'views/dashboard.html',
controller: 'DashboardController',
resolve: {
user: function(SessionService) {
return SessionService.getCurrentUser();
}
}
})
.otherwise({
redirectTo: '/'
});
}]);
ui.router
這裏是如何設置一個基本url。
$stateProvider
.state('contacts', {
url: "/contacts",
templateUrl: 'contacts.html'
})
當我們訪問index.html/contacts時, ‘contacts’狀態將被激活,同時index.html中的ui-view將被’contacts.html’填充。或者,通過transitionTo(‘contacts’)方法將狀態轉變到’contacts’狀態,同時 url 將更新爲index.html/contacts。
通常,url動態部分被稱爲參數,有幾個選項用於指定參數。基本參數如下:
$stateProvider
.state('contacts.detail', {
// 這裏設置了url參數
url: "/contacts/:contactId",
templateUrl: 'contacts.detail.html',
controller: function ($stateParams) {
// If we got here from a url of /contacts/42
expect($stateParams).toBe({contactId: 42});
}
})
或者,你也可以使用花括號的方式來指定參數:
// 與前面的設置方法等效
url: "/contacts/{contactId}"
‘/hello/’ - 只匹配’/hello/’路徑,沒有對斜槓進行特殊處理,這種模式將匹配整個路徑,而不僅僅是一個前綴。
‘/user/:id’ - 匹配’/user/bob’、’/user/1234!!!’,甚至還匹配 ‘/user/’,但是不匹配’/user’和’/user/bob/details’。第二個路徑段將被捕獲作爲參數”id”。
‘/user/{id}’ - 與前面的示例相同,但使用花括號語法。
嵌套狀態的路由控制
在嵌套狀態的路由控制中,默認方式是子狀態的 url 附加到父狀態的 url 之後。
$stateProvider
.state('contacts', {
url: '/contacts',
...
})
.state('contacts.list', {
url: '/list',
...
});
- ‘contacts’狀態將匹配”/contacts”
‘contacts.list’狀態將匹配”/contacts/list”。子狀態的url是附在父狀態的url之後的。
絕對路由(^)
如果你使用絕對 url 匹配的方式,那麼你需要給你的url字符串加上特殊符號”^”。
$stateProvider
.state('contacts', {
url: '/contacts',
...
})
.state('contacts.list', {
url: '^/list',
...
});
路由將成爲:
- ‘contacts’狀態將匹配”/contacts”
- ‘contacts.list’狀態將匹配”/list”。子狀態的url沒有附在父狀態的url之後的,因爲使用了^。
$stateParams 服務
之前看到的 $stateParams服務是一個對象,包含 url 中每個參數的鍵/值。$stateParams可以爲控制器或者服務提供 url 的各個部分。
注意:$stateParams服務必須與一個控制器相關,並且$stateParams中的“鍵/值”也必須事先在那個控制器的url屬性中有定義。
// 如果狀態中 url 屬性是:
url: '/users/:id/details/{type}/{repeat:[0-9]+}?from&to'
// 當瀏覽
'/users/123/details//0'
// $stateParams 對象將是
{ id:'123', type:'', repeat:'0' }
// 當瀏覽
'/users/123/details/default/0?from=there&to=here'
// $stateParams 對象將是
{ id:'123', type:'default', repeat:'0', from:'there', to:'here' }
只有當狀態被激活並且狀態的所有依賴項都被注入時,$stateParams對象才存在。這代表你不能再狀態的resolve函數中使用$stateParams對象,可以使用$state.current.params來代替。
$urlRouterProvider
$urlRouterProvider負責處理在狀態配置中指定的url路由方式之外的 url 請求的路由方式。$urlRouterProvider負責監視$location,當$location改變後,$urlRouterProvider將從一個列表,一個接一個查找匹配項,直到找到。所有 url 都編譯成一個UrlMatcher對象。
命名視圖
在ui-router中,一個$state下可以有多個視圖,它們有各自的模板和控制器。這一點也是ng-route所沒有的, 給了前端路由極大的靈活性。來看例子:
<!-- index.html -->
<body>
<div ui-view="filters"></div>
<div ui-view="tabledata"></div>
<div ui-view="graph"></div>
</body>
這一個模板包含了三個命名的ui-view,可以給它們分別設置模板和控制器:
$stateProvider
.state('report',{
views: {
'filters': {
templateUrl: 'report-filters.html',
controller: function($scope){ ... controller stuff just for filters view ... }
},
'tabledata': {
templateUrl: 'report-table.html',
controller: function($scope){ ... controller stuff just for tabledata view ... }
},
'graph': {
templateUrl: 'report-graph.html',
controller: function($scope){ ... controller stuff just for graph view ... }
}
}
})