首页 > 代码库 > AngularJS学习--- AngularJS中数据双向绑定(two-way data-binding) orderBy step4

AngularJS学习--- AngularJS中数据双向绑定(two-way data-binding) orderBy step4

1.切换工作目录

git checkout step-4  #切换分支,切换到第4步
npm start  #启动项目

2.代码

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">
    {{phone.name}}
    <p>{{phone.snippet}}</p>
  </li>
</ul>

app/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‘;
});

 

 

3.效果

按字母排序:

 

按时间排序:

很明显,相较于step-3,step-4新增加了排序功能

 

4.原理说明

首先,添加了<select> 标签:

<select ng-model="orderProp">
  <option value="http://www.mamicode.com/name">Alphabetical</option>
  <option value="http://www.mamicode.com/age">Newest</option>
</select>

其次,在filter中添加了orderBy:

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

所以,根据angularjs的思想,一是model改变(可能是用户手动选择下拉框导致的),那么根据数据绑定原则(data-binding),view也将适时进行改变.

orderBy api:https://docs.angularjs.org/api/ng/filter/orderBy

orderBy Usage(用法)

In HTML Template Binding(在HTML中的用法)

{{ orderBy_expression | orderBy : expression : reverse}}

In JavaScript(在JS中的用法)

$filter(‘orderBy‘)(array, expression, reverse)

上面的例子是在HTML中用的,默认string类型的数据是按照字母表中数据排序的,而number数字类型的数据是按照数字大小进行排序的.

如果想要倒序,那么可以在上面的option value=http://www.mamicode.com/‘-name‘,加上一个‘-‘即可.

 

5.测试

amosli@amosli-pc:~/develop/angular-phonecat$ npm run protractor 

> angular-phonecat@0.0.0 preprotractor /home/amosli/develop/angular-phonecat
> npm run update-webdriver


> angular-phonecat@0.0.0 preupdate-webdriver /home/amosli/develop/angular-phonecat
> npm install


> angular-phonecat@0.0.0 postinstall /home/amosli/develop/angular-phonecat
> bower install


> angular-phonecat@0.0.0 update-webdriver /home/amosli/develop/angular-phonecat
> webdriver-manager update

selenium standalone is up to date.
chromedriver is up to date.

> angular-phonecat@0.0.0 protractor /home/amosli/develop/angular-phonecat
> protractor test/protractor-conf.js


------------------------------------
PID: 5265 (capability: chrome #1)
------------------------------------

Using ChromeDriver directly...
..

Finished in 5.033 seconds
2 tests, 5 assertions, 0 failures

这里执行的是端到端的测试,测试代码如下:

angular-phonecat/test/e2e/scenarios.js

amosli@amosli-pc:~/develop/angular-phonecat/test/e2e$ cat scenarios.js 
use strict;

/* http://docs.angularjs.org/guide/dev_guide.e2e-testing */

describe(PhoneCat App, function() {

  describe(Phone list view, function() {

    beforeEach(function() {
      browser.get(app/index.html);
    });


    it(should filter the phone list as user types into the search box, function() {

      var phoneList = element.all(by.repeater(phone in phones));
      var query = element(by.model(query));

      expect(phoneList.count()).toBe(3);

      query.sendKeys(nexus);
      expect(phoneList.count()).toBe(1);

      query.clear();
      query.sendKeys(motorola);
      expect(phoneList.count()).toBe(2);
    });


    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)).findElement(by.css(option[value="http://www.mamicode.com/name"])).click();

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