之所以叫雙向數據綁定,當然是由于有一個單向數據綁定了。
那么什么是單向數據綁定呢?簡單來講,我們把C層中的值,傳給V層就是數據由C層綁定到V層。或是V層綁定了C層的數據。我們把這種數據由C層傳給V層的方式,叫做單向數據綁定。
有了上面的說法,雙向就不難理解了。雙向數據綁定就是除了C可以向V傳值以外,V還可以將值反傳給C。這就實現了雙向的數據綁定。
為此,我們在test.html做一下測試,來看看angularjs的雙向數據綁定。
`test.html`
~~~
<!DOCTYPE html>
<html lang="en" ng-app="test">
<head>
<meta charset="UTF-8">
<title>test</title>
<script src="bower_components/angular/angular.js"></script>
</head>
<body ng-controller="ctrl">
<input type="text" ng-model="key" />
<p>key:{{key}}</p>
</body>
<script type="text/javascript">
angular.module('test', [])
.controller('ctrl', function($scope){
$scope.key = 'yunzhi';
})
</script>
</html>
~~~
效果:

> 本來是想給大家上傳一些GIF的,可惜看云并不支持。
當我們改變input中的值時,會發現,{{key}}的值也會隨著變化。
這個數值的傳是這樣的:
`input` -> `$scope.key` -> `{{key}}`
即:V -> C ->V
## 增加排序
下面,我們使用雙向數據綁定來實現ng-repeat的排序。數據的傳輸路徑如下:`<select>` -> `$scope.orderBy` -> `<ng-repeat>` 即:V -> C -> V
實現之前,我們先復習一下上節的內容。當我們輸出關鍵字時,進行了篩選。下面,我們增加一個自動按關鍵字排序的功能。
## 擴展原型
和以前一樣,我們首先完善一下原型。
`yun-zhi/phone-list.template.html`
~~~
<div class="col-md-2">
<p>
Search:
<input ng-model="$ctrl.query" />
</p>
<p>
Sort By:
<select>
<option value="">Alphabetical</option>
<option value="">Newest</option>
</select>
</p>
</div>
~~~

增加按標題字母排序和按發布時間排序。
## 加入屬性
寫到這,我們好像,發現了一個問題。我們想實現按發布時間排序的功能,但我們的數據中,好像沒有發布時間這一項。
`yun-zhi/phone-list.component.js'
~~~
this.phones = [{
name: 'Nexus S',
snippet: 'Fast just got faster with Nexus S.'
},
~~~
怎么辦呢? 簡單,再加一個屬性就好了。在這里,我們給它起個屬性名:`age`,即機型發布的時長。
`yun-zhi/phone-list.component.js'
~~~
angular.
module('yunZhi').
component('phoneList', {
templateUrl: 'yun-zhi/phone-list.template.html',
controller: function PhoneListController() {
this.phones = [{
name: 'Nexus S',
snippet: 'Fast just got faster with Nexus S.',
age: 1
}, {
name: 'Motorola XOOM? with Wi-Fi',
snippet: 'The Next, Next Generation tablet.',
age: 2
}, {
name: 'MOTOROLA XOOM?',
snippet: 'The Next, Next Generation tablet.',
age: 3
}];
}
});
~~~
## 綁定數據
原型有了,現在讓我們將其與angularjs聯系在一起。
### 綁定select
`yun-zhi/phone-list.template.html`
~~~
<select ng-model="$ctrl.orderProp">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
</select>
->{{$ctrl.orderProp}}
~~~
我們為select綁定`$ctrl.orderProp` ,然后給option的value相應的值。在選擇相應的option時,`$ctrl.orderProp`就會變成相應的值。
測試:



的確,我們發現當進行點選時,`$ctrl.orderProp`中的值變化為option中的值了。
### 增加repeat的過濾器
想實現排序效果,還需要將這個值添加到repeat的過濾器中,上一節,我們使用了`filter`過濾器,這節中,我們使用`orderBy`過濾器。
~~~
<li ng-repeat="phone in $ctrl.phones | filter:$ctrl.query | orderBy:$ctrl.orderProp">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
~~~
測試:


的確,點我們進行點選時,發現右側排序的方式變了。
除了上述兩種過濾器外,`angularjs`還為我們內置了其實過濾器,比如:`currency`,`number`.....
> 參考: https://docs.angularjs.org/api/ng/filter
這些過濾器,有些是使用在數組上的,有一些是使用在類型上的,具體的可以google一下,看看它們的作用。
當然了,隨著教程的深入,我們也會去構造自己的過濾器。
### 增加默認值
上面雖然實現了排序,但有個小問題,就是當頁面刷新時,`select`中并沒有默認選中第一條,這是由于我們還沒有給`$ctrl.orderProp`指定一個默認值。
下面,我們在C層中,為其設定一個初始值.
`yun-zhi/phone-list.component.js'
~~~
+ this.orderProp = 'age';
~~~
刷新測試:

最后,我們規整代碼:
* * * * *
`yun-zhi/phone-list.component.js`
~~~
angular.
module('yunZhi').
component('phoneList', {
templateUrl: 'yun-zhi/phone-list.template.html',
controller: function PhoneListController() {
this.phones = [{
name: 'Nexus S',
snippet: 'Fast just got faster with Nexus S.',
age: 1
}, {
name: 'Motorola XOOM? with Wi-Fi',
snippet: 'The Next, Next Generation tablet.',
age: 2
}, {
name: 'MOTOROLA XOOM?',
snippet: 'The Next, Next Generation tablet.',
age: 3
}];
this.orderProp = 'age';
}
});
~~~
`yun-zhi/phone-list.template.html`
~~~
<div class="container-fluid">
<div class="row">
<div class="col-md-2">
<p>
Search:
<input ng-model="$ctrl.query" />
</p>
<p>
Sort By:
<select ng-model="$ctrl.orderProp">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
</select>
</p>
</div>
<div class="col-md-10">
<!--Body content-->
<ul class="phones">
<li ng-repeat="phone in $ctrl.phones | filter:$ctrl.query | orderBy:$ctrl.orderProp">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul>
</div>
</div>
</div>
~~~
- 前言
- 第一章:準備知識
- 第一節:GIT
- 第二節:Node.js
- 第三節:http-server
- 第四節:bower
- 第五節:firefox+chrome
- 第二章:官方示例教程
- 第零節:Hello Yunzhier
- 第一節:靜態模板
- 第二節:MVC
- 回調函數
- 第三節:組件
- 第四節:重構組件
- 2.4.1 調用組件
- 2.4.2 規劃目錄結構
- 2.4.3 剝離V層
- 2.4.4 大話測試
- 第五節:循環過濾器
- 第六節:雙向數據綁定
- 第七節:XHR與依賴注入
- 第八節:添加縮略圖
- 第九節:模擬頁面跳轉
- 2.9.1 使用bower
- 2.9.2 使用grunt
- 第十節:完善手機詳情頁
- 第十一節:自定義過濾器
- 第十二節:行為處理
- 第十三節:封裝請求
- 第十四節:應用動畫
- 第十五節:總結
- 第三章:菜譜管理示例
- 第四章:總結