AngularJS語法詳解(續(xù))
src和href屬性
Angularjs中src應(yīng)寫成ng-src,href應(yīng)寫成ng-href 例如:
<img ng-src="/images/cats/{{favoriteCat}}">
<a ng-href="/shop/category={{number}}">Some text</a>
表達(dá)式
在模板中可以進(jìn)行簡(jiǎn)單的數(shù)學(xué)運(yùn)算、比較運(yùn)算、布爾運(yùn)算、位運(yùn)算、引用數(shù)組、和對(duì)象符號(hào)等 盡管我們可以使用表達(dá)式做很多事情,但是表達(dá)式是使用一個(gè)自定義的解釋器來執(zhí)行的(Angular的一部分),而不是用Javascript得eval()函數(shù)執(zhí)行的,所以局限性較大。
雖然很多方面這里的表達(dá)式比Javascript更嚴(yán)格,但是他們對(duì)undefined和null的容錯(cuò)性更好,如果遇到錯(cuò)誤,模板只是簡(jiǎn)單的什么都不顯示,而不會(huì)拋出一個(gè)NullPointerException錯(cuò)誤。 例如:
<div ng-controller='SomeController'>
<div>{{computer() /10 }}</div> //雖然是合法的,但是它把業(yè)務(wù)邏輯放到模板中了,應(yīng)避免這種做法
</div>
區(qū)分UI和控制器的職責(zé)
控制器是綁定在特定DOM片段上的,這些片段就是他們需要負(fù)責(zé)管理的內(nèi)容。有兩種主要的方法可以把控制器關(guān)聯(lián)到DOM節(jié)點(diǎn)上,一種在模板中通過ng-controller聲明,第二種是通過路由把它綁定到一個(gè)動(dòng)態(tài)加載的DOM模板片段上,這個(gè)模板叫視圖。 我們可以創(chuàng)建嵌套的控制器,他們可以通過繼承數(shù)結(jié)構(gòu)來共享數(shù)據(jù)模型和函數(shù),真實(shí)的嵌套發(fā)生在$scope對(duì)象上,通過內(nèi)部的原始繼承機(jī)制,父控制器對(duì)象的$scope會(huì)被傳遞到內(nèi)部嵌套的$scope(所有屬性,包括函數(shù))。例如:
<div ng-controller="ParentController">
<div ng-controller="ChildController">...</div>
</div>
利用$scope暴漏模型數(shù)據(jù)
可以顯示創(chuàng)建$scope屬性,例如$scope.count = 5。還可以間接的通過模板自身創(chuàng)建數(shù)據(jù)模型。
通過表達(dá)式。例如
<button ng-click='count=3'>Set count to three</button>
在表單項(xiàng)上使用ng-model
與表達(dá)式類似,ng-model上指定的模型參數(shù)同樣工作在外層控制器內(nèi)。唯一的不同點(diǎn)在于,這樣會(huì)在表單項(xiàng)和指定的模型之間建立雙向綁定關(guān)系。
使用watch監(jiān)控?cái)?shù)據(jù)模型的變化
$watch的函數(shù)簽名是: $watch(watchFn,watchAction,deepWatch)
watchFn是一個(gè)帶有Angular表達(dá)式或者函數(shù)的字符串,它會(huì)返回被監(jiān)控的數(shù)據(jù)模型的當(dāng)前值。 watchAction是一個(gè)函數(shù)或者表達(dá)式,當(dāng)watchFn發(fā)生變化時(shí)調(diào)用。其函數(shù)簽名為:
function(newValue,oldValue,scope) deepWatch 如果設(shè)置為true,這個(gè)可選的布爾值參數(shù)將會(huì)命令A(yù)ngular去檢查被監(jiān)控對(duì)象的每一個(gè)屬性是否發(fā)生了變化。如果你向監(jiān)控?cái)?shù)組中的元素,或者對(duì)象上的所有屬性,而不是值監(jiān)控一個(gè)簡(jiǎn)單的值,你就可以使用這個(gè)參數(shù)。注意,Angular需要遍歷數(shù)組或者對(duì)象,如果集合比較大,那么運(yùn)算復(fù)雜呢就會(huì)比較的重。
$watch函數(shù)會(huì)返回一個(gè)函數(shù),當(dāng)你不需要接收變更通知時(shí),可以用這個(gè)返回的函數(shù)注銷監(jiān)控器。
如果我們需要監(jiān)控一個(gè)屬性,然后接著注銷監(jiān)控,我們就可以使用以下的代碼: var dereg = $scope.$watch('someModel.someProperty',callbackOnChange());
... dereg();
實(shí)例代碼如下:
<html ng-app>
<head>
<title>Your Shopping Cart</title>
<script type="text/javascript">
function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title:'Paint pots',quantity:8,price:3.95},
{title:'Polka dots',quantity:17,price:12.95},
{title:'Pebbles',quantity:5,price:6.95}
];
$scope.totalCart = function() {
var total = 0;
for (var i=0,len=$scope.items.length;i<len;i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
return total;
}
$scope.subtotal = function() {
return $scope.totalCart() - $scope.bill.discount;
}
function calculateDiscount(newValue,oldValue,scope) {
$scope.bill.discount = newValue > 100 ? 10 : 0;
}//這里的watchAction函數(shù)
$scope.$watch($scope.totalCart,calculateDiscount);//這里的watch函數(shù)
}
</script>
</head>
<body>
<div ng-controller="CartController">
<div ng-repeat='item in items'>
<span>{{item.title}}</span>
<input ng-model='item.quantity'>
<span>{{item.price | currency}}</span>
<span>{{item.price * item.quantity | currency}}</span>
</div>
<div>Total: {{totalCart()| currency }}</div>
<div>Discount: {{bill.discount | currency}}</div>
<div>SubTotal: {{subtotal() | currency}}</div>
</div>
<script type="text/javascript" src="angular.min.js"></script>
</body>
</html>
上面的watch存在性能問題,calculateTotals函數(shù)執(zhí)行了6次,其中三次是因?yàn)檠瓑模看窝h(huán),都會(huì)重新渲染數(shù)據(jù)。
下面是改良后的代碼
<html ng-app>
<head>
<title>Your Shopping Cart</title>
<script type="text/javascript">
function CartController($scope) {
$scope.bill = {};
$scope.items = [
{title:'Paint pots',quantity:8,price:3.95},
{title:'Polka dots',quantity:17,price:12.95},
{title:'Pebbles',quantity:5,price:6.95}
];
var totalCart = function() {
var total = 0;
for (var i=0,len=$scope.items.length;i<len;i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.totalcart = total;
$scope.bill.discount = total > 100 ? 10 :0;
$scope.bill.subtotal = total - $scope.bill.discount;
}
$scope.$watch('items',totalCart,true);//只用watch著items的變化
}
</script>
</head>
<body>
<div ng-controller="CartController">
<div ng-repeat='item in items'>
<span>{{item.title}}</span>
<input ng-model='item.quantity'>
<span>{{item.price | currency}}</span>
<span>{{item.price * item.quantity | currency}}</span>
</div>
<div>Total: {{bill.totalcart| currency }}</div>
<div>Discount: {{bill.discount | currency}}</div>
<div>SubTotal: {{bill.subtotal | currency}}</div>
</div>
<script type="text/javascript" src="angular.min.js"></script>
</body>
</html>
對(duì)于大型的itms數(shù)組來說,如果每次在Angular顯示頁面時(shí)只重新計(jì)算bill屬性,那么性能會(huì)好很多。通過創(chuàng)建一個(gè)帶有watchFn的$watch函數(shù),我們可以實(shí)現(xiàn)這一點(diǎn)。
$scope.$watch(
var totalCart = function() {
var total = 0;
for (var i=0,len=$scope.items.length;i<len;i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.totalcart = total;
$scope.bill.discount = total > 100 ? 10 :0;
$scope.bill.subtotal = total - $scope.bill.discount;
});
監(jiān)控多個(gè)東西
如果你想監(jiān)控多個(gè)屬性或者對(duì)象,并且當(dāng)其中任何一個(gè)發(fā)生變化時(shí)就會(huì)去執(zhí)行一個(gè)函數(shù),你有兩種基本的選擇:
監(jiān)控把這些屬性連接起來之后的值
把他們放在一個(gè)數(shù)組或者對(duì)象中,然后給deepWAtch參數(shù)傳遞一個(gè)值
分別說明:
在第一種情況下,如果你的作用域中存在一個(gè)things對(duì)象,它帶有兩個(gè)屬性a和b,當(dāng)這兩個(gè)屬性發(fā)生變化時(shí)都需要執(zhí)行callMe()函數(shù),你可以同時(shí)監(jiān)控這兩個(gè)屬性 $scope.$watch('things.a + things.b',callMe(...));
當(dāng)列表非常長(zhǎng),你就需要寫一個(gè)函數(shù)來返回連接之后的值。
在第二種情況下,需要監(jiān)控things對(duì)象的所有屬性,你可以這么做:
$scope.$watch('things',callMe(...),true);
使用module組織依賴關(guān)系
provider(name,Object OR constructor()) 說明: 一個(gè)可配置的服務(wù),創(chuàng)建邏輯比較的復(fù)雜。如果你傳遞了一個(gè)Object作為參數(shù),那么這個(gè)Object對(duì)象必須帶有一個(gè)名為$get的函數(shù),這個(gè)函數(shù)需要返回服務(wù)的名稱。否則,angularjs會(huì)認(rèn)為你傳遞的時(shí)一個(gè)構(gòu)造函數(shù),調(diào)用構(gòu)造函數(shù)會(huì)返回服務(wù)實(shí)例對(duì)象。
factory(name,$get Function()) 說明:一個(gè)不可配置的服務(wù),創(chuàng)建邏輯比較的復(fù)雜。你需要指定一個(gè)函數(shù),當(dāng)調(diào)用這個(gè)函數(shù)時(shí),會(huì)返回服務(wù)實(shí)例??梢钥闯蓀rovider(name,{$get:$getFunction()})的形式。
service(name,constructor()) 一個(gè)不可配置的服務(wù),創(chuàng)建邏輯比較的簡(jiǎn)單。與上面的provider函數(shù)的constructor參數(shù)類似,Angular調(diào)用他可以創(chuàng)建服務(wù)實(shí)例。
使用module factory的例子
<html ng-app='ShoppingModule'>
<head>
<title>Your Shopping Cart</title>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var ShoppingModule = angular.module('ShoppingModule',[]);
ShoppingModule.factory('Items',function() {
var items = {};
items.query = function() {
return [
{title:'Paint pots',description:'Pots full of Paint',price:3.95},
{title:'Paint pots',description:'Pots full of Paint',price:3.95},
{title:'Paint pots',description:'Pots full of Paint',price:3.95}
];
};
return items;
});
function ShoppingController($scope,Items) {
$scope.items = Items.query();
}
</script>
</head>
<body ng-controller='ShoppingController'>
<h1>Shop!!</h1>
<table>
<tr ng-repeat='item in items'>
<td>{{item.title}}</td>
<td>{{item.description}}</td>
<td>{{item.price | currency}}</td>
</tr>
</table>
</body>
</html>
引入第三方模塊
在大多數(shù)應(yīng)用中,創(chuàng)建供所有代碼使用的單個(gè)模塊,并把所有依賴的東西放入這個(gè)模塊中,這樣就會(huì)工作的很好。但是,如果你打算使用第三方包提供的服務(wù)或者指令,他們一般都帶有自己的模塊,你需要在應(yīng)用模塊中定義依賴關(guān)心才能引用他們。 例如:
var appMod = angular.module('app',['Snazzy','Super']);
關(guān)于filter的例子
<html ng-app='ShoppingModule'>
<head>
<title>Your Shopping Cart</title>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
var ShoppingModule = angular.module('ShoppingModule',[]);
ShoppingModule.filter('titleCase',function() {
var titleCaseFilter = function(input) {
var words = input.split(' ');
for(var i=0;i<words.length;i++) {
words[i] = words[0].charAt(0).toUpperCase() + words[i].slice(1);
}
return words.join(' ');
};
return titleCaseFilter;
});
function ShoppingController($scope) {
$scope.pageHeading = 'this is a test case';
}
</script>
</head>
<body ng-controller='ShoppingController'>
<h1>{{pageHeading | titleCase}}</h1>
</body>
</html>
相關(guān)文章
AngularJS標(biāo)簽頁tab選項(xiàng)卡切換功能經(jīng)典實(shí)例詳解
這篇文章主要介紹了AngularJS實(shí)現(xiàn)標(biāo)簽頁tab選項(xiàng)卡功能,結(jié)合實(shí)例形式總結(jié)分析了各種常用的tab選項(xiàng)卡切換操作實(shí)現(xiàn)技巧與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2018-05-05如何在Angular8.0下使用ngx-translate進(jìn)行國(guó)際化配置
這篇文章主要介紹了如何在Angular8.0下使用ngx-translate進(jìn)行國(guó)際化配置,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Angular+Ionic使用queryParams實(shí)現(xiàn)跳轉(zhuǎn)頁傳值的方法
這篇文章主要介紹了Angular+Ionic使用queryParams實(shí)現(xiàn)跳轉(zhuǎn)頁傳值的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Angular 4中如何顯示內(nèi)容的CSS樣式示例代碼
這篇文章主要給大家介紹了關(guān)于Angular 4中如何顯示內(nèi)容的CSS樣式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11詳解AngularJS中module模塊的導(dǎo)入導(dǎo)出
本文給大家介紹angularjs中module模塊的導(dǎo)入導(dǎo)出,涉及到angularjs module相關(guān)知識(shí),對(duì)angularjs module感興趣的朋友一起看看吧2015-12-12Angular異步執(zhí)行學(xué)習(xí)之zone.js使用
這篇文章主要為大家介紹了Angular異步執(zhí)行學(xué)習(xí)之zone.js使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06