1. 程式人生 > >angular指令(二)--內置指令

angular指令(二)--內置指令

花括號 use mit cnblogs counter 運算表達式 事件 資源 特定

一、基礎ng 屬性指令:

? ng-href
? ng-src
? ng-disabled
? ng-checked
? ng-readonly
? ng-selected
? ng-class
? ng-style

布爾屬性的有:

ng-disabled、ng-readonly、ng-checked、ng-selected

類布爾屬性有:

ng-href、ng-src

二、在指令中使用子作用域

? ng-app

? ng-controller

? ng-include

使用ng-include可以加載、編譯並包含外部HTML片段到當前的應用中。模板的URL被限制
在與應用文檔相同的域和協議下,可以通過白名單或包裝成被信任的值來突破限制。更進一步,
需要考慮跨域資源共享(Cross-Origin Resource Sharing,CORS)和同源規則(Same Origin Policy)
來確保模板可以在任何瀏覽器中正常加載。例如,所有瀏覽器都不能進行跨域的請求,部分瀏覽
器也不能訪問file://協議的資源。

在開發中,可以通過命令行命令chrome --allow-file-access-from-files來
禁止CORS錯誤。只在緊急情況下使用這個方法,比如你的老板正站在你身後,
並且所有事情都無法正常工作。

在同一個元素上添加onload屬性可以在模板加載完成後執行一個表達式。
要記住,使用ng-include時AngularJS會自動創建一個子作用域。如果你想使用某個特定的作
用域,例如ControllerA的作用域,必須在同一個DOM元素上添加ng-controller ="ControllerA"
指令,這樣當模板加載完成後,不會像往常一樣從外部作用域繼承並創建一個新的子作用域。下
面看一個例子:

<div ng-include="/myTemplateName.html"
ng-controller="MyController"
ng-init="name = ‘World‘">
Hello {{ name }}
</div>

? ng-switch

這個指令和ng-switch-when及on="propertyName"一起使用,可以在propertyName發生變
化時渲染不同指令到視圖中。在下面的例子中,當person.name是Ari時,文本域下面的div會顯
示出來,並且這個人會獲得勝利:

<input type="text" ng-model="person.name"/>
<div ng-switch on="person.name">
<p ng-switch-default>And the winner is</p>
<h1 ng-switch-when="Ari">{{ person.name }}</h1>
</div>

註意,在switch被調用之前我們用ng-switch-default來輸出默認值。

? ng-view

ng-view指令用來設置將被路由管理和放置在HTML中的視圖的位置。
? ng-if

使用ng-if指令可以完全根據表達式的值在DOM中生成或移除一個元素。如果賦值給ng-if
的表達式的值是false,那對應的元素將會從DOM中移除,否則對應元素的一個克隆將被重新插
入DOM中。
ng-if同no-show和ng-hide指令最本質的區別是,它不是通過CSS顯示或隱藏DOM節點,而
是真正生成或移除節點。
當一個元素被ng-if從DOM中移除,同它關聯的作用域也會被銷毀。而且當它重新加入DOM
中時,會通過原型繼承從它的父作用域生成一個新的作用域。
同時有一個重要的細節需要知道,ngIf重新創建元素時用的是它們編譯後的狀態。如果ng-if

內部的代碼加載之後被jQuery修改過(例如用.addClass),那麽當ng-if的表達式值為false時,
這個DOM元素會被移除,表達式再次成為true時這個元素及其內部的子元素會被重新插入
DOM,此時這些元素的狀態會是它們的原始狀態,而不是它們上次被移除時的狀態。也就是說
無論用jQuery的.addClass添加了什麽類都不會存在了。

<div ng-if="2+2===5">
Won‘t see this DOM node, not even in the source code
</div>
<div ng-if="2+2===4">
Hi, I do exist
</div>

? ng-repeat

ng-repeat用來遍歷一個集合或為集合中的每個元素生成一個模板實例。集合中的每個元素
都會被賦予自己的模板和作用域。同時每個模板實例的作用域中都會暴露一些特殊的屬性。
? $index:遍歷的進度(0...length-1)。
? $first:當元素是遍歷的第一個時值為true。
? $middle:當元素處於第一個和最後元素之間時值為true。
? $last:當元素是遍歷的最後一個時值為true。
? $even:當$index值是偶數時值為true。
? $odd:當$index值是奇數時值為true。
下面的例子展示了如何用$odd和$even來制作一個紅藍相間的列表。記住,JavaScript中數組
的索引從0開始,因此我們用!$even和!$odd來將$even和$odd的布爾值反轉。

<ul ng-controller="PeopleController">
<li ng-repeat="person in people" ng-class="{even: !$even, odd: !$odd}">
{{person.name}} lives in {{person.city}}
</li>
</ul>
.odd {
background-color: blue;
}
.even {
background-color: red;
}
angular.module(‘myApp‘,[])
.controller(‘PeopleController‘,function($scope) {
$scope.people = [
{name: "Ari", city: "San Francisco"},
{name: "Erik", city: "Seattle"}
];
});

? ng-init

ng-init指令用來在指令被調用時設置內部作用域的初始狀態。

? ng-bind

盡管可以在視圖中使用{{ }}模板語法(AngularJS內置的方式),我們也可以通過ng-bind
指令實現同樣的行為。

<body ng-init="greeting=‘HelloWorld‘">
<p ng-bind="greeting"></p>
</body>

HTML加載含有{{ }}語法的元素後並不會立刻渲染它們,導致未渲染內容閃爍(Flash of
Unrendered Content,FOUC)。我可以用ng-bind將內容同元素綁定在一起避免FOUC。內容會被
當作子文本節點渲染到含有ng-bind指令的元素內。

? ng-cloak

除使用ng-bind來避免未渲染元素閃爍,還可以在含有{{ }}的元素上使用ng-cloak指令:
<body ng-init="greeting=‘HelloWorld‘">
<p ng-cloak>{{ greeting }}</p>
</body>
ng-cloak指令會將內部元素隱藏,直到路由調用對應的頁面時才顯示出來。

? ng-bind-template

<div
ng-bind-template="{{message}}{{name}}">
</div>

? ng-model

ng-model指令用來將input、select、text area或自定義表單控件同包含它們的作用域中
的屬性進行綁定。它可以提供並處理表單驗證功能,在元素上設置相關的CSS類(ng-valid、
ng-invalid等),並負責在父表單中註冊控件。
它將當前作用域中運算表達式的值同給定的元素進行綁定。如果屬性並不存在,它會隱式創
建並將其添加到當前作用域中。
我們應該始終用ngModel來綁定$scope上一個數據模型內的屬性,而不是$scope上的屬性,
這可以避免在作用域或後代作用域中發生屬性覆蓋。
例如:

<input type="text"
ng-model="modelName.someProperty" />

? ng-show/ng-hide

ng-show和ng-hide根據所給表達式的值來顯示或隱藏HTML元素。當賦值給ng-show指令的
值為false時元素會被隱藏。類似地,當賦值給ng-hide指令的值為true時元素也會被隱藏。
元素的顯示或隱藏是通過移除或添加ng-hide這個CSS類來實現的。.ng-hide類被預先定義
在了AngularJS的CSS文件中,並且它的display屬性的值為none(用了!important標記)。

<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>
<div ng-hide="2 + 2 == 5">
2 + 2 isn‘t 5, don‘t hide
</div>
<div ng-hide="2 + 2 == 4">
2 + 2 is 4, do hide
</div>

? ng-change

這個指令會在表單輸入發生變化時計算給定表達式的值。因為要處理表單輸入,這個指令要
和ngModel聯合起來使用。

<div ng-controller="EquationController">
<input type="text"

ng-model="equation.x"
ng-change="change()" />
<code>{{ equation.output }}</code>
</div>
angular.module(‘myApp‘,[])
.controller(‘EquationController‘,function($scope) {
$scope.equation = {};
$scope.change = function() {
$scope.equation.output
= parseInt($scope.equation.x) + 2;
};
});

上面的例子中,只要文本輸入字段中的內容發生了變化就會改變equation.x的值,進而運
行change()函數。

? ng-form

ng-form用來在一個表單內部嵌套另一個表單。普通的HTML <form>標簽不允許嵌套,但
ng-form可以。
這意味著內部所有的子表單都合法時,外部的表單才會合法。這對於用ng-repeat動態創建
表單是非常有用的。
由於不能通過字符插值來給輸入元素動態地生成name屬性,所以需要將ng-form指令內每組
重復的輸入字段都包含在一個外部表單元素內。
下面的CSS類會根據表單的驗證狀態自動設置:
? 表單合法時設置ng-valid;
? 表單不合法時設置ng-invlid;
? 表單未進行修改時設置ng-pristion;
? 表單進行過修改時設置ng-dirty。
Angular不會將表單提交到服務器,除非它指定了action屬性。要指定提交表單時調用哪個
JavaScript方法,使用下面兩個指令中的一個。
? ng-submit:在表單元素上使用。
? ng-click:在第一個按鈕或submit類型(input[type=submit])的輸入字段上使用。
為了避免處理程序被多次調用,只使用下面兩個指令中的一個。
下面的例子展示了如何通過服務器返回的JSON數據動態生成一個表單。我們用ng-loop來遍
歷從服務器取回的所有數據。由於不能動態生成name屬性,而我們又需要這個屬性做驗證,所以
在循環的過程中會為每一個字段都生成一個新表單。
由於AngularJS中用來取代<form>的ng-form指令可以嵌套,並且外部表單在所有子表單都合
法之前一直處於不合法狀態,因此我們可以在動態生成子表單的同時使用表單驗證功能。是的,
魚和熊掌可以兼得。
下面先看一下我們硬編碼的JSON數據,把它假設成是從服務器返回的:

angular.module(‘myApp‘,[])
.controller(‘FormController‘,function($scope) {
$scope.fields = [
{placeholder: ‘Username‘, isRequired: true},
{placeholder: ‘Password‘, isRequired: true},
{placeholder: ‘Email (optional)‘, isRequired: false}
];
$scope.submitForm = function() {
alert("it works!");
};
});

下面用這些數據生成一個有驗證功能的動態表單:

<form name="signup_form"
ng-controller="FormController"
ng-submit="submitForm()" novalidate>
<div ng-repeat="field in fields"
ng-form="signup_form_input">
<input type="text"
name="dynamic_input"
ng-required="field.isRequired"
ng-model="field.name"
placeholder="{{field.placeholder}}" />
<div
ng-show="signup_form_input.dynamic_input.$dirty &&
signup_form_input.dynamic_input.$invalid">
<span class="error"
ng-show="signup_form_input.dynamic_input.$error.required">
The field is required.
</span>
</div>
</div>
<button type="submit"
ng-disabled="signup_form.$invalid">
Submit All
</button>
</form>
input.ng-invalid {
border: 1px solid red;
}
input.ng-valid {
border: 1px solid green;
} 

? ng-click

ng-click用來指定一個元素被點擊時調用的方法或表達式。

<div ng-controller="CounterController">
<button ng-click="count = count + 1"
ng-init="count=0">
Increment
</button>
count: {{ count }}
<button ng-click="decrement()">

Decrement
</button>
<div>
angular.module(‘myApp‘,[])
.controller(‘CounterController‘, function($scope) {
$scope.decrement = function() {
$scope.count = $scope.count - 1;
};
})

? ng-select

ng-select用來將數據同HTML的<select>元素進行綁定。這個指令可以和ng-model以及
ng-options指令一同使用,構建精細且表現優良的動態表單。
ng-options的值可以是一個內涵表達式(comprehension expression),其實這只是一種有趣
的說法,簡單來說就是它可以接受一個數組或對象,並對它們進行循環,將內部的內容提供給
select標簽內部的選項。它可以是下面兩種形式。
? 數組作為數據源:
? 用數組中的值做標簽;
? 用數組中的值作為選中的標簽;
? 用數組中的值做標簽組;
? 用數組中的值作為選中的標簽組。
? 對象作為數據源:
? 用對象的鍵?值(key-value)做標簽;
? 用對象的鍵?值作為選中的標簽;
? 用對象的鍵?值作為標簽組;
? 用對象的鍵?值作為選中的標簽組。
下面看一個ng-select指令的實例:

<div ng-controller="CityController">
<select ng-model="city"
ng-options="city.name for city in cities">
<option value="">Choose City</option>
</select>
Best City: {{ city.name }}
</div>
angular.module(‘myApp‘,[])
.controller(‘CityController‘,function($scope) {
$scope.cities = [
{name: ‘Seattle‘},
{name: ‘San Francisco‘},
{name: ‘Chicago‘},
{name: ‘New York‘},
{name: ‘Boston‘}
];
}); 

? ng-submit

ng-submit用來將表達式同onsubmit事件進行綁定。這個指令同時會阻止默認行為(發送請
求並重新加載頁面),除非表單不含有action屬性。

<form ng-submit="submit()"
ng-controller="FormController">
Enter text and hit enter:
<input type="text"
ng-model="person.name"
name="person.name" />
<input type="submit"
name="person.name"
value="Submit" />
<code>people={{people}}</code>
<ul ng-repeat="(index, object) in people">
<li>{{ object.name }}</li>
</ul>
</form>
angular.module(‘myApp‘,[])
.controller(‘FormController‘,function($scope) {
$scope.person = {
name: null
};
$scope.people = [];
$scope.submit = function() {
if ($scope.person.name) {
$scope.people.push({name: $scope.person.name});
$scope.person.name = ‘‘;
}
};
});

? ng-class

使用ng-class 動態設置元素的類,方法是綁定一個代表所有需要添加的類的表達式。重復
的類不會添加。當表達式發生變化,先前添加的類會被移除,新類會被添加。
下面的例子會用ng-class在一個隨機數大於5時將.red類添加到一個div上:

<div ng-controller="LotteryController">
<div ng-class="{red: x > 5}"
ng-if="x > 5">
You won!
</div>
<button ng-click="x = generateNumber()"
ng-init="x = 0">
Draw Number
</button>
<p>Number is: {{ x }}</p>
</div>

.red {
background-color: red;
}
angular.module(‘myApp‘,[])
.controller(‘LotteryController‘, function($scope) {
$scope.generateNumber = function() {
return Math.floor((Math.random()*10)+1);
};
});

? ng-attr-(suffix)

當AngularJS編譯DOM時會查找花括號{{ some expression }}內的表達式。這些表達式會
被自動註冊到$watch服務中並更新到$digest循環中,成為它的一部分:
<-- updated when`someExpression` on the$scope
is updated -->
<h1>Hello{{someExpression}}</h1>
有時瀏覽器會對屬性會進行很苛刻的限制。SVG就是一個例子:
<svg>
<circle cx="{{ cx }}"></circle>
</svg>
運行上面的代碼會拋出一個錯誤,指出我們有一個非法屬性。可以用ng-attr-cx來解決這
個問題。註意,cx位於這個名稱的尾部。在這個屬性中,通過用{{ }}來寫表達式,達到前面提
到的目的。
<svg>
<circle ng-attr-cx="{{ cx }}"><circle>
</svg>

angular指令(二)--內置指令