22@name Tutorial: 4 - Two-way Data Binding
33@description
44
5- <h2 style="color: red">This page has not been updated for AngularJS 1.0 yet</h2>
6-
75<ul doc:tutorial-nav="4"></ul>
86
97
@@ -29,19 +27,19 @@ __`app/index.html`:__
2927...
3028 <ul class="controls">
3129 <li>
32- Search: <input type="text" ng: model="query"/ >
30+ Search: <input ng- model="query">
3331 </li>
3432 <li>
3533 Sort by:
36- <select ng: model="orderProp">
34+ <select ng- model="orderProp">
3735 <option value="name">Alphabetical</option>
3836 <option value="age">Newest</option>
3937 </select>
4038 </li>
4139 </ul>
4240
4341 <ul class="phones">
44- <li ng: repeat="phone in phones.$ filter( query).$ orderBy( orderProp) ">
42+ <li ng- repeat="phone in phones | filter: query | orderBy: orderProp">
4543 {{phone.name}}
4644 <p>{{phone.snippet}}</p>
4745 </li>
@@ -54,14 +52,14 @@ We made the following changes to the `index.html` template:
5452* First, we added a `<select>` html element named `orderProp`, so that our users can pick from the
5553two provided sorting options.
5654
57- <img src="img/tutorial/tutorial_04-06_final .png">
55+ <img src="img/tutorial/tutorial_04.png">
5856
59- * We then chained the `$ filter` method with {@link api/angular.module.ng.$filter.orderBy `$ orderBy`} method to
60- further process the input into the repeater. `$ orderBy` is a utility method similar to {@link
61- api/angular.module.ng.$filter.filter `$filter`}, but instead of filtering an array, it reorders it .
57+ * We then chained the `filter` filter with {@link api/angular.module.ng.$filter.orderBy `orderBy`}
58+ filter to further process the input into the repeater. `orderBy` is a filter that takes an input
59+ array, copies it and reorders the copy which is then returned .
6260
6361Angular creates a two way data-binding between the select element and the `orderProp` model.
64- `orderProp` is then used as the input for the `$ orderBy` method .
62+ `orderProp` is then used as the input for the `orderBy` filter .
6563
6664As we discussed in the section about data-binding and the repeater in step 3, whenever the model
6765changes (for example because a user changes the order with the select drop down menu), Angular's
@@ -76,8 +74,8 @@ __`app/js/controller.js`:__
7674<pre>
7775/* App Controllers */
7876
79- function PhoneListCtrl() {
80- this .phones = [{"name": "Nexus S",
77+ function PhoneListCtrl($scope ) {
78+ $scope .phones = [{"name": "Nexus S",
8179 "snippet": "Fast just got faster with Nexus S.",
8280 "age": 0},
8381 {"name": "Motorola XOOM™ with Wi-Fi",
@@ -87,16 +85,16 @@ function PhoneListCtrl() {
8785 "snippet": "The Next, Next Generation tablet.",
8886 "age": 2}];
8987
90- this .orderProp = 'age';
88+ $scope .orderProp = 'age';
9189}
9290</pre>
9391
9492* We modified the `phones` model - the array of phones - and added an `age` property to each phone
9593record. This property is used to order phones by age.
9694
9795* We added a line to the controller that sets the default value of `orderProp` to `age`. If we had
98- not set the default value here, angular would have used the value of the first `<option>` element
99- (`'name'`) when it initialized the data model .
96+ not set the default value here, the model would stay uninitialized until our user would pick an
97+ option from the drop down menu .
10098
10199 This is a good time to talk about two-way data-binding. Notice that when the app is loaded in the
102100browser, "Newest" is selected in the drop down menu. This is because we set `orderProp` to `'age'`
@@ -120,17 +118,18 @@ describe('PhoneCat controllers', function() {
120118 var scope, $browser, ctrl;
121119
122120 beforeEach(function() {
123- ctrl = new PhoneListCtrl();
121+ scope = {};
122+ ctrl = new PhoneListCtrl(scope);
124123 });
125124
126125
127126 it('should create "phones" model with 3 phones', function() {
128- expect(ctrl .phones.length).toBe(3);
127+ expect(scope .phones.length).toBe(3);
129128 });
130129
131130
132131 it('should set the default value of orderProp model', function() {
133- expect(ctrl .orderProp).toBe('age');
132+ expect(scope .orderProp).toBe('age');
134133 });
135134 });
136135});
@@ -162,13 +161,13 @@ __`test/e2e/scenarios.js`:__
162161 // narrow the dataset to make the test assertions shorter
163162 input('query').enter('tablet');
164163
165- expect(repeater('.phones li', 'Phone List').column('a ')).
164+ expect(repeater('.phones li', 'Phone List').column('phone.name ')).
166165 toEqual(["Motorola XOOM\u2122 with Wi-Fi",
167166 "MOTOROLA XOOM\u2122"]);
168167
169168 select('orderProp').option('alphabetical');
170169
171- expect(repeater('.phones li', 'Phone List').column('a ')).
170+ expect(repeater('.phones li', 'Phone List').column('phone.name ')).
172171 toEqual(["MOTOROLA XOOM\u2122",
173172 "Motorola XOOM\u2122 with Wi-Fi"]);
174173 });
@@ -184,9 +183,12 @@ Angular's server}.
184183
185184# Experiments
186185
186+ <div style="display:none">
187+ !!!!! TODO(i): we need to fix select/option to support unknown option !!!!!
187188* In the `PhoneListCtrl` controller, remove the statement that sets the `orderProp` value and
188189you'll see that the ordering as well as the current selection in the dropdown menu will default to
189190"Alphabetical".
191+ </div>
190192
191193* Add an `{{orderProp}}` binding into the `index.html` template to display its current value as
192194text.
0 commit comments