Reproduced Angularjs Getting Started Tutorial 03: iterators

Source: Internet
Author: User

We did a lot of basic training in the previous step, so now we can do some simple things. We're going to join the full-text search feature (yes, this is really very simple!) )。 At the same time, we will write an end-to-end test, because a good end-to-end test can be very helpful. It monitors your application and reports quickly in the event of a return.

Please reset your working directory:

Git checkout-f step-3

Our app now has a search box. Notice that the list of phones on the page varies with the user's input in the search box.

The most important differences between steps 2 and 3 are listed below. You can see the whole difference on GitHub.

Controller

We do not make any changes to the controller.

Template

App/index.html

<Divclass= "Container-fluid">  <Divclass= "Row-fluid">    <Divclass= "Span2">      <!--Sidebar Content -Search:<inputNg-model= "Query">    </Div>    <Divclass= "Span10">      <!--Body Content -      <ulclass= "Phones">        <Ling-repeat= "Phone in phones | filter:query">{{Phone.name}}<P>{{Phone.snippet}}</P>        </Li>      </ul>       </Div>  </Div></Div>

We now add a <input> label and use Angularjs's $filter function to handle the input of the ngrepeat instruction.

This allows the user to enter a search condition and immediately be able to see the search results for the phone list. Let's try to explain the new code:

    • Data binding: This is a core feature of Angularjs. When the page loads, Angularjs binds it to a variable of the same name in the data model, based on the name of the input box's property value, to ensure the synchronization of the two.

      In this code, the name of the data entered by the user in the input box query is immediately entered as the filter for the list iterator ( phone in phones | filter: query '). When the data model causes iterator input to change, iterators can efficiently update the DOM to reflect the latest state of the data model.

    • Use filter the filter: query the value used by the filter function to create a query new array that contains only matching records.

      ngRepeatfilterThe view is automatically updated based on the array of cell phone record data generated by the filter. The whole process is transparent to the developer.

Test

In step 2, we learned how to write and run a test. Unit testing is very handy for testing the controllers and other components we write with JS, but it is not easy to test DOM operations and application integration. For these, end-to-end testing is a better choice.

The search feature is implemented entirely through templates and data binding, so our first end-to-end test verifies that these features are in line with our expectations.

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

Although the syntax of this test code looks very much like the unit tests we wrote earlier with Jasmine, the end-to-end test uses the interface provided by the Angularjs end-to-end tester.

Run an end-to-end test and open one of the following in the browser's new tab page:

    • node. JS User: Http://localhost:8000/test/e2e/runner.html
    • Users using a different HTTP server:http://localhost:[port-number]/[context-path]/test/e2e/runner.html
    • Visitors: http://angular.github.com/angular-phonecat/step-3/test/e2e/runner.html

This test verifies that the search box and the iterator are properly integrated. You can see how easy it is to write an end-to-end test in Angularjs. Although this example is just a simple test, it is easy to use it to build any of the complex, readable end-to-end tests.

Practice
  • index.htmlAdd a {{query}} binding to the template to display query the current values of the model in real time, and then see how they change depending on the value in the input box.
  • Now let's take a look at how we let the value of the query model appear on the page header of the HTML.

    You might think it's OK to title add a binding on the label like this:

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

    However, when you reload the page, you simply can't get the desired result. This is because the query model is body valid only within the scope of the element definition.

      <ng-controller= "Phonelistctrl">

    If you want to <title> bind an element to a query model, you ngController must move the declaration to the HTML element, because it is title body the common ancestor of the element.

      <ng-app ng-controller= "Phonelistctrl">

    Be careful to body delete the declaration on the element ng-controller .

    When binding two curly braces on the title element can achieve our goal, but you may find that the page is loading when they are displayed to the user to see. A better solution is to use ngbind or ngbindtemplate directives, which are not visible to the user when the page is loaded:

      <ng-bind-template= "Google phone Gallery: {{query}}">Google Phone Gallery</title>

  • test/e2e/scenarios.jsAdd the describe following end-to-end test code in the block:

    It (' should display the current filter value withina element      withID ' 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 ');  });

    Refresh the browser, and the end-to-end tester will report the test failure. In order for the test to pass, edit index.html , add one id为“status” div or the p element, the content is a query binding, plus a Current filter: prefix. For example:

      <div id= "Status" >current filter: {{query}}</div>

  • Add a statement to the end-to-end test pause(); and run it again. You will find the tester paused! This gives you the opportunity to see the status of your app while the test is running. The test app is real-time! You can change the search content to prove it. With a little experience you will know how critical it is to quickly find problems in end-to-end testing.

Summarize

We have now added full-text search functionality and completed a test to prove that the search is right! Now let's move on to step 4来 to see how our mobile app adds sorting capabilities.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.