美文网首页一起学AngularJS
【一起学AngularJS】第六章、双向数据绑定

【一起学AngularJS】第六章、双向数据绑定

作者: 40ab6525bf35 | 来源:发表于2016-03-10 14:37 被阅读127次

本章节中,我们将为之前展示的手机信息列表提供一个排序功能。要想实现动态排序的功能,我们只需要新建一个模型属性,并且把它和循环器绑定在一起,剩下的就交给数据绑定去完成了。
相比上一章中的例子,本章中的例子多添加了一个下拉菜单,它允许用户自己控制手机列表的显示顺序。首先我们把代码切换到step-4:

git checkout -f step-4

刷新浏览器查看效果(假设之前你已经运行了上一章的例子)。你可以在线看效果

模版

app/index.html

Search: <input ng-model="query">
Sort by:
<select ng-model="orderProp">
  <option value="name">Alphabetical</option>
  <option value="age">Newest</option>
</select>


<ul class="phones">
  <li ng-repeat="phone in phones | filter:query | orderBy:orderProp">
    <span>{{phone.name}}</span>
    <p>{{phone.snippet}}</p>
  </li>
</ul>

代码对index.html主要做了以下几点改动:

  • 第一布我们添加一个名为orderProp<select>标签元素,这样用户就能从提供的两种排序中选择自己想要的排序方式了。
  • 第二步我们再之前的filter过滤器链中添加一个orderBy过滤器用来对结果进行排序。orderBy过滤器的输入为一个数组,对其进行排序并且返回排序后的数组。

这个例子中,Angular在<select>元素和orderProp数据模型之间建立双向数据绑定,然后orderBy过滤器就可以用它作为输入,并且返回结果了。
上一章中我们讨论了关于循环器的数据绑定,只要模型数据发生变化(比如用户下拉排序菜单选择了不通的排序方式),Angular的数据绑定功能将确保页面会同步展示最新结果。其他的手工控制代码都不用自己写。

控制器

app/js/controllers.js:

var phonecatApp = angular.module('phonecatApp', []);

phonecatApp.controller('PhoneListCtrl', function ($scope) {
  $scope.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}
  ];

  $scope.orderProp = 'age';
});

上述代码主要包含以下改动:

  • 首先我们修改了phones数据模型,为每条手机记录添加了一个age属性。页面将支持根据这个属性来排序。
  • 另外我们在接下来的一行中把orderProp的默认值设成age(告诉页面第一次载入时按照age排序)。如果这里没有设置默认值,页面在载入的时候将是未排序过的,直到用户从下拉菜单中选择了一个排序方式。

这个例子能非常好的说明双向绑定这个概念。当页面载入后,我们可以看到下拉框显示的是"Newest",这是因为我们把orderProp默认设置为了age。这是一次从数据模型到UI的单向绑定。另外一方面,当我们选择下拉菜单的"Alphabetical",后台中的手机数组列表就会被重新排列,这就是从UI到数据模型的单向绑定。这两者结合起来,就是数据的双向绑定了。

测试

这次的改动将涉及单元测试和E2E测试两个测试。我们先看以下单元测试:
test/unit/controllersSpec.js:

describe('PhoneCat controllers', function() {

  describe('PhoneListCtrl', function(){
    var scope, ctrl;

    beforeEach(module('phonecatApp'));

    beforeEach(inject(function($controller) {
      scope = {};
      ctrl = $controller('PhoneListCtrl', {$scope:scope});
    }));

    it('should create "phones" model with 3 phones', function() {
      expect(scope.phones.length).toBe(3);
    });


    it('should set the default value of orderProp model', function() {
      expect(scope.orderProp).toBe('age');
    });
  });
});

上述单元测试代码将验证orderProp默认值是否设置成功。
我们使用了Jasmine的API来把控制器的构造过程抽取出来放入了beforeEach模块中,这将使得它能被父模块describe中的所有测试所共享。
你将会从Karma的控制台输出中看到以下消息:

Chrome 22.0: Executed 2 of 2 SUCCESS (0.021 secs / 0.001 secs)

下面让我们来看看E2E测试,以下是代码:
test/e2e/scenarios.js:

...
it('should be possible to control phone order via the drop down select box', function() {

  var phoneNameColumn = element.all(by.repeater('phone in phones').column('phone.name'));
  var query = element(by.model('query'));

  function getNames() {
    return phoneNameColumn.map(function(elm) {
      return elm.getText();
    });
  }

  query.sendKeys('tablet'); //let's narrow the dataset to make the test assertions shorter

  expect(getNames()).toEqual([
    "Motorola XOOM\u2122 with Wi-Fi",
    "MOTOROLA XOOM\u2122"
  ]);

  element(by.model('orderProp')).element(by.css('option[value="name"]')).click();

  expect(getNames()).toEqual([
    "MOTOROLA XOOM\u2122",
    "Motorola XOOM\u2122 with Wi-Fi"
  ]);
});...

E2E测试将用来验证下拉选择框的排序功能是否正常。你可以通过npm run protractor来运行这个测试用例。

实验小能手

  1. PhoneListCtrl控制器代码中,把$scope.orderProp = 'age';这句话注释掉,然后你就会看到Angular会为页面上的下拉框添加了一个新的空白选项(Unknown),并且当前的列表也是未经排序的。
  2. 添加一个{{orderProp}}数据绑定用来查看当前的排序方式。
  3. 想要倒排某个排序?很简单,尝试添加一个新的select选项:<option value="-age">Oldest</option>

总结

现在我们已经为网站添加了排序功能,下一章,我们将学习Angular的服务体系和依赖注入。

相关文章

  • Ionic ng-model 数据双向绑定

    ionic 使用AngularJS ng-model 实现数据双向绑定 AngularJS 实例 绑定输入框的值到...

  • AngularJS的数据双向绑定是怎么实现的?

    ?: 关于 AngularJS 的数据绑定 单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别:...

  • Vue.js初次尝试,简单指令(三)

    到目前为止,我们已经会写Angularjs的双向数据绑定,那么今天也将一起来整理一下Vue.js的双向数据绑定。简...

  • 美团面试总结

    1.angularJS双向绑定实现2.双向绑定的其他实现3.使用get,set实现双向数据绑定4.三列布局实现的三...

  • MVVM双向数据绑定的个人理解

    AngularJS 的脏检查机制 AngularJS的双向数据绑定采用的脏检查机制,所谓“脏检查”,就是检测到数据...

  • AngularJs基础

    AngularJs核心特性 MVVM 双向数据绑定(Model-View-ViewModel)model变化,...

  • AngularJs双向数据绑定

    简介 单项数据绑定:最简单的理解如果我们有一个input想要获取里面的值负值给一个变量,那么我们需要给in...

  • Angularjs与Angular2双向绑定原理

    1、angularjs(1.x)数据双向绑定原理 AngularJs 为 scope 模型上设置了一个 监听队列,...

  • Angular.js问题总结

    1.angular 的数据绑定采用什么机制?详述原理 脏检查机制。 双向数据绑定是 AngularJS 的核心机制...

  • 2018-01-19

    在AngularJs中,使用jQuery添加dom对象来使用数据双向绑定失效。 $(document).on("c...

网友评论

    本文标题:【一起学AngularJS】第六章、双向数据绑定

    本文链接:https://www.haomeiwen.com/subject/hqytlttx.html