99re热视频这里只精品,久久久天堂国产精品女人,国产av一区二区三区,久久久精品成人免费看片,99久久精品免费看国产一区二区三区

6. 迭代器過(guò)濾

2018-02-24 16:14 更新

我們?cè)谏弦徊阶隽撕芏嗷A(chǔ)性的訓(xùn)練,所以現(xiàn)在我們可以來(lái)做一些簡(jiǎn)單的事情嘍。我們要加入全文檢索功能(沒(méi)錯(cuò),這個(gè)真的非常簡(jiǎn)單?。?。同時(shí),我們也會(huì)寫(xiě)一個(gè)端到端測(cè)試,因?yàn)橐粋€(gè)好的端到端測(cè)試可以幫上很大忙。它監(jiān)視著你的應(yīng)用,并且在發(fā)生回歸的時(shí)候迅速報(bào)告。

請(qǐng)重置工作目錄:

git checkout -f step-3

我們的應(yīng)用現(xiàn)在有了一個(gè)搜索框。注意到頁(yè)面上的手機(jī)列表隨著用戶在搜索框中的輸入而變化。

步驟2和步驟3之間最重要的不同在下面列出。你可以在GitHub里看到完整的差別。

控制器

我們對(duì)控制器不做任何修改。

模板

app/index.html

<div class="container-fluid">
  <div class="row-fluid">
    <div class="span2">
      <!--Sidebar content-->

      Search: <input ng-model="query">

    </div>
    <div class="span10">
      <!--Body content-->

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

       </div>
  </div>
</div>

我們現(xiàn)在添加了一個(gè)<input>標(biāo)簽,并且使用AngularJS的$filter函數(shù)來(lái)處理ngRepeat指令的輸入。

這樣允許用戶輸入一個(gè)搜索條件,立刻就能看到對(duì)電話列表的搜索結(jié)果。我們來(lái)解釋一下新的代碼:

  • 數(shù)據(jù)綁定: 這是AngularJS的一個(gè)核心特性。當(dāng)頁(yè)面加載的時(shí)候,AngularJS會(huì)根據(jù)輸入框的屬性值名字,將其與數(shù)據(jù)模型中相同名字的變量綁定在一起,以確保兩者的同步性。

    在這段代碼中,用戶在輸入框中輸入的數(shù)據(jù)名字稱(chēng)作query,會(huì)立刻作為列表迭代器(phone in phones | filter:query`)其過(guò)濾器的輸入。當(dāng)數(shù)據(jù)模型引起迭代器輸入變化的時(shí)候,迭代器可以高效得更新DOM將數(shù)據(jù)模型最新的狀態(tài)反映出來(lái)。

  • 使用filter過(guò)濾器:filter函數(shù)使用query的值來(lái)創(chuàng)建一個(gè)只包含匹配query記錄的新數(shù)組。

    ngRepeat會(huì)根據(jù)filter過(guò)濾器生成的手機(jī)記錄數(shù)據(jù)數(shù)組來(lái)自動(dòng)更新視圖。整個(gè)過(guò)程對(duì)于開(kāi)發(fā)者來(lái)說(shuō)都是透明的。

測(cè)試

在步驟2,我們學(xué)習(xí)了編寫(xiě)和運(yùn)行一個(gè)測(cè)試的方法。單元測(cè)試用來(lái)測(cè)試我們用js編寫(xiě)的控制器和其他組件都非常方便,但是不能方便的對(duì)DOM操作和應(yīng)用集成進(jìn)行測(cè)試。對(duì)于這些來(lái)說(shuō),端到端測(cè)試是一個(gè)更好的選擇。

搜索特性是完全通過(guò)模板和數(shù)據(jù)綁定實(shí)現(xiàn)的,所以我們的第一個(gè)端到端測(cè)試就來(lái)驗(yàn)證這些特性是否符合我們的預(yù)期。

test/e2e/scenarios.js:

describe('PhoneCat App', function() {

  describe('Phone list view', function() {

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

    it('should filter the phone list as user types into the search box', function() {
      expect(repeater('.phones li').count()).toBe(3);

      input('query').enter('nexus');
      expect(repeater('.phones li').count()).toBe(1);

      input('query').enter('motorola');
      expect(repeater('.phones li').count()).toBe(2);
    });
  });
});

盡管這段測(cè)試代碼的語(yǔ)法看起來(lái)和我們之前用Jasmine寫(xiě)的單元測(cè)試非常像,但是端到端測(cè)試使用的是AngularJS端到端測(cè)試器提供的接口。

運(yùn)行一個(gè)端到端測(cè)試,在瀏覽器新標(biāo)簽頁(yè)中打開(kāi)下面任意一個(gè):

這個(gè)測(cè)試驗(yàn)證了搜素框和迭代器被正確地集成起來(lái)。你可以發(fā)現(xiàn),在AngularJS里寫(xiě)一個(gè)端到端測(cè)試多么的簡(jiǎn)單。盡管這個(gè)例子僅僅是一個(gè)簡(jiǎn)單的測(cè)試,但是用它來(lái)構(gòu)建任何一個(gè)復(fù)雜、可讀的端到端測(cè)試都很容易。

練習(xí)

  • index.html模板中添加一個(gè){{query}}綁定來(lái)實(shí)時(shí)顯示query模型的當(dāng)前值,然后觀察他們是如何根據(jù)輸入框中的值而變化。
  • 現(xiàn)在我們來(lái)看一下我們?cè)趺醋?code>query模型的值出現(xiàn)在HTML的頁(yè)面標(biāo)題上。

    你或許認(rèn)為像下面這樣在title標(biāo)簽上加上一個(gè)綁定就行了:

      <title>Google Phone Gallery: {{query}}</title>

    但是,當(dāng)你重載頁(yè)面的時(shí)候,你根本沒(méi)辦法得到期望的結(jié)果。這是因?yàn)?code>query模型僅僅在body元素定義的作用域內(nèi)才有效。

      <body ng-controller="PhoneListCtrl">

    如果你想讓<title>元素綁定上query模型,你必須把ngController聲明移動(dòng)到HTML元素上,因?yàn)樗?code>title和body元素的共同祖先。

      <html ng-app ng-controller="PhoneListCtrl">

    一定要注意把body元素上的ng-controller聲明給刪了。

    當(dāng)綁定兩個(gè)花括號(hào)在title元素上可以實(shí)現(xiàn)我們的目標(biāo),但是你或許發(fā)現(xiàn)了,頁(yè)面正加載的時(shí)候它們已經(jīng)顯示給用戶看了。一個(gè)更好的解決方案是使用ngBind或者ngBindTemplate指令,它們?cè)陧?yè)面加載時(shí)對(duì)用戶是不可見(jiàn)的:

      <title ng-bind-template="Google Phone Gallery: {{query}}">Google Phone Gallery</title>
  • test/e2e/scenarios.jsdescribe塊中加入下面這些端到端測(cè)試代碼:

      it('should display the current filter value within an element with id "status"',
          function() {
              expect(element('#status').text()).toMatch(/Current filter: \s*$/);
              input('query').enter('nexus');
              expect(element('#status').text()).toMatch(/Current filter: nexus\s*$/);
              //alternative version of the last assertion that tests just the value of the binding
              using('#status').expect(binding('query')).toBe('nexus');
      });

    刷新瀏覽器,端到端測(cè)試器會(huì)報(bào)告測(cè)試失敗。為了讓測(cè)試通過(guò),編輯index.html,添加一個(gè)id為“status”div或者p元素,內(nèi)容是一個(gè)query綁定,再加上Current filter:前綴。例如:

      <div id="status">Current filter: {{query}}</div>
  • 在端到端測(cè)試?yán)锩婕右粭lpause();語(yǔ)句,重新跑一遍。你將發(fā)現(xiàn)測(cè)試器暫停了!這樣允許你有機(jī)會(huì)在測(cè)試運(yùn)行過(guò)程中查看你應(yīng)用的狀態(tài)。測(cè)試應(yīng)用是實(shí)時(shí)的!你可以更換搜索內(nèi)容來(lái)證明。稍有經(jīng)驗(yàn)?zāi)憔蜁?huì)知道,這對(duì)于在端到端測(cè)試中迅速找到問(wèn)題是多么的關(guān)鍵。

總結(jié)

我們現(xiàn)在添加了全文搜索功能,并且完成一個(gè)測(cè)試證明了搜索是對(duì)的!現(xiàn)在讓我們繼續(xù)到步驟4來(lái)看看給我們的手機(jī)應(yīng)用增加排序功能。

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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)