之所以叫双向数据绑定,当然是由于有一个单向数据绑定了。
那么什么是单向数据绑定呢?简单来讲,我们把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>
~~~
效果:
![](https://box.kancloud.cn/2016-07-26_5796fd1191bf9.png)
> 本来是想给大家上传一些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>
~~~
![](https://box.kancloud.cn/2016-07-26_5796fd11adc4e.png)
增加按标题字母排序和按发布时间排序。
## 加入属性
写到这,我们好像,发现了一个问题。我们想实现按发布时间排序的功能,但我们的数据中,好像没有发布时间这一项。
`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`就会变成相应的值。
测试:
![](https://box.kancloud.cn/2016-07-26_5796fd11c595b.png)
![](https://box.kancloud.cn/2016-07-26_5796fd11e6d05.png)
![](https://box.kancloud.cn/2016-07-26_5796fd1207845.png)
的确,我们发现当进行点选时,`$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>
~~~
测试:
![](https://box.kancloud.cn/2016-07-26_5796fd1222c3e.png)
![](https://box.kancloud.cn/2016-07-26_5796fd1243aaf.png)
的确,点我们进行点选时,发现右侧排序的方式变了。
除了上述两种过滤器外,`angularjs`还为我们内置了其实过滤器,比如:`currency`,`number`.....
> 参考: https://docs.angularjs.org/api/ng/filter
这些过滤器,有些是使用在数组上的,有一些是使用在类型上的,具体的可以google一下,看看它们的作用。
当然了,随着教程的深入,我们也会去构造自己的过滤器。
### 增加默认值
上面虽然实现了排序,但有个小问题,就是当页面刷新时,`select`中并没有默认选中第一条,这是由于我们还没有给`$ctrl.orderProp`指定一个默认值。
下面,我们在C层中,为其设定一个初始值.
`yun-zhi/phone-list.component.js'
~~~
+ this.orderProp = 'age';
~~~
刷新测试:
![](https://box.kancloud.cn/2016-07-26_5796fd125db57.png)
最后,我们规整代码:
* * * * *
`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
- 第十节:完善手机详情页
- 第十一节:自定义过滤器
- 第十二节:行为处理
- 第十三节:封装请求
- 第十四节:应用动画
- 第十五节:总结
- 第三章:菜谱管理示例
- 第四章:总结