AngularJS 雙路數(shù)據(jù)綁定

2022-04-15 14:33 更新

雙路數(shù)據(jù)綁定

在這一步中,你將添加一個功能,讓你的用戶控制手機列表中的項目的排序。這個動態(tài)排序由創(chuàng)建一個新模塊屬性來實現(xiàn),用迭代器接通它們,并且讓數(shù)據(jù)綁定來完成剩余工作。

  • 除了搜索框,應用顯示了一個下拉菜單,允許用戶 控制列出的手機的排序。

把工作空間重置到第四步

git checkout -f step-4

刷新你的瀏覽器或在線檢查這一步:Step 4 Live Demo

下面列出了第四步和第五步之間的最重要的區(qū)別。你可以在GitHub里看到完整的差異。

模板

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模板的改變:

  • 首先,我們添加了一個<select> html元素,命名為orderProp,因此我們的用戶可以從兩個提供的排序選擇中選一個。
  • 然后,我們把filter篩選器連與orderBy?篩選器連綴,以更進一步處理輸入到迭代器的處理。orderBy是一個篩選器,取用一個輸入數(shù)組,復制它,之后返回一個副本,重排序這個副本。

Angular在select元素以及orderProp模塊之間創(chuàng)建了雙路數(shù)據(jù)綁定。然后orderProp被用作針對orderBy篩選器的輸入。

正如我們在這一節(jié)第三步中討論的,關于數(shù)據(jù)綁定和迭代器,每當模塊變化時(比如說因為用戶通過選擇下拉菜單改變了順序),Angular的數(shù)據(jù)綁定將導致該視圖自動更新。不臃腫的DOM操作代碼是必要的!

控制器

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模塊——手機的數(shù)組——并把一個age屬性添加到每個手機記錄中。屬性被用于根據(jù)年代排序手機。

  • 我們給控制器添加了一行,把orderProp的默認值設置為age。如果我們還沒有在這里設置一個默認值,orderBy篩選器會保持未初始化,直到我們的用戶從下拉菜單中挑了一個選項。

    這是講解雙路數(shù)據(jù)綁定的好時候。注意,當應用在瀏覽器中載入的時候,下拉菜單中的“最新”被選中。這是因為我們在控制器中把orderProp設置為'age'。從我們的模塊到UI的方向中的綁定工作也同樣?,F(xiàn)在,如果你選擇了下拉菜單中的“Alphabetically(字母表排序)”,模塊也將被更新,而且重排序了手機。這是數(shù)據(jù)綁定在反方向中所做的工作——從UI到模塊。

測試

我們所做的變化將在單元測試和端到端測試中被驗證。讓我們先看一看單元測試。

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');
    });
  });
});

單元測試現(xiàn)在核實了默認的排序?qū)傩栽O置。

我們使用Jasmins的API,把控制器架構(gòu)抽出到beforeEach塊,它由所有的父describe塊中的測試共享。

現(xiàn)在你應該在Karma選項卡中看到了以下輸出:

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

讓我們把注意力帶回到端到端測試。

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"
      ]);
    });...

端到端測試核實了選擇框的排序機制正在正常工作。

現(xiàn)在你可以重新運行npm run protractor以查看測試運行。

實驗

  • PhoneListCtrl控制器中,移除設置orderProp值的狀態(tài),你將看到Angular給下拉列表臨時地添加了一個新的空白("unknown")選項,而且排序?qū)⒛J為無序/自然排序。

  • 把一個{{orderProp}}綁定到index.html模板上,從而把它的當前值顯示為文本。

  • 在排序值前面添加一個-符號來逆轉(zhuǎn)排序順序:<option value="-age">Oldest</option>

總結(jié)

現(xiàn)在我們已經(jīng)添加了列表排序,并測試了應用,前往第五步 XHR和依賴注入以學習關于Angular服務,以及Angular如何使用依賴性注入。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號