aboutsummaryrefslogtreecommitdiffstats
path: root/docs/content/tutorial/step_03.ngdoc
diff options
context:
space:
mode:
Diffstat (limited to 'docs/content/tutorial/step_03.ngdoc')
-rwxr-xr-xdocs/content/tutorial/step_03.ngdoc250
1 files changed, 142 insertions, 108 deletions
diff --git a/docs/content/tutorial/step_03.ngdoc b/docs/content/tutorial/step_03.ngdoc
index 4333636d..812f58bb 100755
--- a/docs/content/tutorial/step_03.ngdoc
+++ b/docs/content/tutorial/step_03.ngdoc
@@ -1,108 +1,142 @@
-@workInProgress
-@ngdoc overview
-@name Tutorial: Step 3
-@description
-<table id="tutorial_nav">
-<tr>
- <td id="previous_step">{@link tutorial.step_02 Previous}</td>
- <td id="step_result">{@link http://angular.github.com/angular-phonecat/step-3/app Example}</td>
- <td id="tut_home">{@link tutorial Tutorial Home}</td>
- <td id="code_diff">{@link
- https://github.com/angular/angular-phonecat/commit/a03815f8fb00217f5f9c1d3ef83282f79818e706 Code
- Diff}</td>
- <td id="next_step">{@link tutorial.step_04 Next}</td>
-</tr>
-</table>
-
-We did a lot of work in laying the foundation of our app in the last step, so now we'll do
-something simple, and add full text search. We will also write an end-to-end test, because a good
-end-to-end test is a good friend. It stays with your app, keeps an eye on it, and quickly detects
-regressions.
-
-__`app/index.html`:__
-<pre>
-...
- Fulltext Search: <input name="query"/>
-
- <ul class="phones">
- <li ng:repeat="phone in phones.$filter(query)">
- {{phone.name}}
- <p>{{phone.snippet}}</p>
- </li>
- </ul>
-...
-</pre>
-__`test/e2e/scenarios.js`:__
-<pre>
-/* jasmine-like end2end tests go here */
-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);
- });
- });
-});
-</pre>
-
-## Discussion:
-
-We continued using the same controller that we set up in Step 2, but we added the following
-features to our app:
-
-* __Search Box:__ A standard HTML `<input>` tag combined with angular's {@link
-angular.Array.filter $filter} utility (added to the repeater) lets a user type in search criteria
-and immediately see the effects of their search on the phone list. This new code demonstrates the
-following:
-
- * Two way Data-binding. This is one of the core features in angular. When the page loads,
- angular binds the name of the input box to a variable of the same name in the data model and
- keeps the two in sync.
-
-In this example, the data that you type into the input box (named __`query`__) is immediately
-available as a filter input in the list repeater (`phone in phones.$filter(`__`query`__`)`).
-Whenever the data model changes and this change causes the input to the repeater to change, the
-repeater will efficiently update the DOM to reflect the current state of the model.
-
- * Use of `$filter` in a template. The `$filter` function is one of several built-in {@link
- angular.Array angular functions} that augment JavaScript arrays during their evaluation as
- angular expressions. In {@link guide.expression angular expressions}, these array utilities are
- available as array methods. (They are prefixed with a $ to avoid naming collisions.)
-
- * `ng:repeat` automatically shrinks and grows the number of phones in the View, via DOM
- manipulation that is completely transparent to the developer. If you've written any DOM
- manipulation code, this should make you happy.
-
-* __CSS:__ We added in some minimal CSS to the file we set up in Step 0: `./css/app.css`.
-
-* __Testing:__ To run the end to end test, open http://localhost:8000/test/e2e/runner.html in
-your browser. This end-to-end test shows the following:
-
- * Proof that the search box and the repeater are correctly wired together.
-
- * How easy it is to write end-to-end tests. This is just a simple test, but the point here is
- to show how easy it is to set up a functional, readable, end-to-end test.
-
-<table id="tutorial_nav">
-<tr>
- <td id="previous_step">{@link tutorial.step_02 Previous}</td>
- <td id="step_result">{@link http://angular.github.com/angular-phonecat/step-3/app Example}</td>
- <td id="tut_home">{@link tutorial Tutorial Home}</td>
- <td id="code_diff">{@link
- https://github.com/angular/angular-phonecat/commit/a03815f8fb00217f5f9c1d3ef83282f79818e706 Code
- Diff}</td>
- <td id="next_step">{@link tutorial.step_04 Next}</td>
-</tr>
-</table>
+@ngdoc overview
+@name Tutorial: Step 3
+@description
+<table id="tutorial_nav">
+<tr>
+ <td id="previous_step">{@link tutorial.step_02 Previous}</td>
+ <td id="step_result">{@link http://angular.github.com/angular-phonecat/step-3/app Live
+ Demo}</td>
+ <td id="tut_home">{@link tutorial Tutorial Home}</td>
+<td id="code_diff">{@link https://github.com/angular/angular-phonecat/compare/step-2...step-3 Code
+Diff}</td>
+ <td id="next_step">{@link tutorial.step_04 Next}</td>
+</tr>
+</table>
+
+We did a lot of work in laying a foundation for the app in the last step, so now we'll do
+something simple, and add full text search (yes, it will be simple!). We will also write an
+end-to-end test, because a good end-to-end test is a good friend. It stays with your app, keeps an
+eye on it, and quickly detects regressions.
+
+1. Reset your workspace to Step 3 using:
+
+ git checkout --force step-3
+
+ or
+
+ ./goto_step.sh 3
+
+2. Refresh your browser or check the app out on {@link
+http://angular.github.com/angular-phonecat/step-3/app our server}. The app now has a search box.
+The phone list on the page changes depending on what a user types into the search box.
+
+The most important changes are listed below. You can see the full diff on {@link
+https://github.com/angular/angular-phonecat/compare/step-2...step-3
+ GitHub}:
+
+
+## Controller
+
+We made no changes to the controller.
+
+
+## Template
+
+__`app/index.html`:__
+<pre>
+...
+ Fulltext Search: <input name="query"/>
+
+ <ul class="phones">
+ <li ng:repeat="phone in phones.$filter(query)">
+ {{phone.name}}
+ <p>{{phone.snippet}}</p>
+ </li>
+ </ul>
+...
+</pre>
+
+We added a standard HTML `<input>` tag and use angular's {@link angular.Array.filter $filter}
+function to process the input for the `ng:repeater`.
+
+This lets a user enter search criteria and immediately see the effects of their search on the
+phone list. This new code demonstrates the following:
+
+* Data-binding. This is one of the core features in angular. When the page loads, angular binds
+the name of the input box to a variable of the same name in the data model and keeps the two in
+sync.
+
+ In this code, the data that a user types into the input box (named __`query`__) is immediately
+ available as a filter input in the list repeater (`phone in phones.$filter(`__`query`__`)`).
+ When changes to the data model cause the repeater's input to change, the repeater efficiently
+ updates the DOM to reflect the current state of the model.
+
+* Use of `$filter`. The `{@link angular.Array.filter $filter}` method, uses the `query` value, to
+create a new array that contains only those records that match the `query`.
+
+* `ng:repeat` automatically updates the view in response to the changing number of phones returned
+by the `$filter`. The process is completely transparent to the developer.
+
+## Test
+
+In Step 2, we learned how to write and run unit tests. Unit tests are perfect for testing
+controllers and other components of our application written in JavaScript, but they can't easily
+test DOM manipulation or the wiring of our application. For these, an end-to-end test is a much
+better choice.
+
+The search feature was fully implemented via templates and data-binding, so we'll write our first
+end-to-end test, to verify that the feature works.
+
+__`test/e2e/scenarios.js`:__
+<pre>
+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);
+ });
+ });
+});
+</pre>
+
+Even though the syntax of this test looks very much like our controller unit test written with
+Jasmine, the end-to-end test uses APIs of {@link
+https://docs.google.com/document/d/11L8htLKrh6c92foV71ytYpiKkeKpM4_a5-9c3HywfIc/edit?hl=en&pli=1#
+angular's end-to-end test runner}.
+
+To run the end-to-end test, open the following in a new browser tab:
+
+* node.js users: http://localhost:8000/test/e2e/runner.html
+* users with other http servers:
+http://localhost:[*port-number*]/[*context-path*]/test/e2e/runner.html
+* casual reader: http://angular.github.com/angular-phonecat/step-3/test/e2e/runner.html
+
+This test verifies that the search box and the repeater are correctly wired together. Notice how
+easy it is to write end-to-end tests in angular. Although this example is for a simple test, it
+really is that easy to set up any functional, readable, end-to-end test.
+
+Now that you've verified everything, go to Step 4 to learn how to add sorting capability to the
+phone list app.
+
+<table id="tutorial_nav">
+<tr>
+ <td id="previous_step">{@link tutorial.step_02 Previous}</td>
+ <td id="step_result">{@link http://angular.github.com/angular-phonecat/step-3/app Live
+ Demo}</td>
+ <td id="tut_home">{@link tutorial Tutorial Home}</td>
+<td id="code_diff">{@link https://github.com/angular/angular-phonecat/compare/step-2...step-3 Code
+Diff}</td>
+ <td id="next_step">{@link tutorial.step_04 Next}</td>
+</tr>
+</table>