forked from angular/code.angularjs.org
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstep_10.html
134 lines (97 loc) · 4.57 KB
/
step_10.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<h1><code ng:non-bindable=""></code>
<span class="hint"></span>
</h1>
<div><ul doc-tutorial-nav="10"></ul>
<p>In this step, you will add a clickable phone image swapper to the phone details page.</p>
<div doc-tutorial-reset="10">
</div>
<p>The phone details view displays one large image of the current phone and several smaller thumbnail
images. It would be great if we could replace the large image with any of the thumbnails just by
clicking on the desired thumbnail image. Let's have a look at how we can do this with Angular.</p>
<p>The most important changes are listed below. You can see the full diff on <a href="https://github.com/angular/angular-phonecat/compare/step-9...step-10">GitHub</a>:</p>
<h3>Controller</h3>
<p><strong><code>app/js/controllers.js</code>:</strong>
<pre class="prettyprint linenums">
...
function PhoneDetailCtrl($scope, $routeParams, $http) {
$http.get('phones/' + $routeParams.phoneId + '.json').success(function(data) {
$scope.phone = data;
$scope.mainImageUrl = data.images[0];
});
$scope.setImage = function(imageUrl) {
$scope.mainImageUrl = imageUrl;
}
}
//PhoneDetailCtrl.$inject = ['$scope', '$routeParams', '$http'];
</pre>
<p>In the <code>PhoneDetailCtrl</code> controller, we created the <code>mainImageUrl</code> model property and set its
default value to the first phone image URL.</p>
<p>We also created a <code>setImage</code> event handler function that will change the value of <code>mainImageUrl</code>.</p>
<h3>Template</h3>
<p><strong><code>app/partials/phone-detail.html</code>:</strong>
<pre class="prettyprint linenums">
<img ng-src="{{mainImageUrl}}" class="phone">
...
<ul class="phone-thumbs">
<li ng-repeat="img in phone.images">
<img ng-src="{{img}}" ng-click="setImage(img)">
</li>
</ul>
...
</pre>
<p>We bound the <code>ngSrc</code> directive of the large image to the <code>mainImageUrl</code> property.</p>
<p>We also registered an <a href="api/ng.directive:ngClick"><code><code>ngClick</code></code></a>
handler with thumbnail images. When a user clicks on one of the thumbnail images, the handler will
use the <code>setImage</code> event handler function to change the value of the <code>mainImageUrl</code> property to the
URL of the thumbnail image.</p>
<div style="display: none">
TODO!
<img class="diagram" src="img/tutorial/tutorial_10-11_final.png">
</div>
<h3>Test</h3>
<p>To verify this new feature, we added two end-to-end tests. One verifies that the main image is set
to the first phone image by default. The second test clicks on several thumbnail images and
verifies that the main image changed appropriately.</p>
<p><strong><code>test/e2e/scenarios.js</code>:</strong>
<pre class="prettyprint linenums">
...
describe('Phone detail view', function() {
...
it('should display the first phone image as the main phone image', function() {
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.0.jpg');
});
it('should swap main image if a thumbnail image is clicked on', function() {
element('.phone-thumbs li:nth-child(3) img').click();
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.2.jpg');
element('.phone-thumbs li:nth-child(1) img').click();
expect(element('img.phone').attr('src')).toBe('img/phones/nexus-s.0.jpg');
});
});
});
</pre>
<p>You can now rerun <code>./scripts/e2e-test.sh</code> or refresh the browser tab with the end-to-end test
runner to see the tests run, or you can see them running on <a href="http://angular.github.com/angular-phonecat/step-8/test/e2e/runner.html">Angular's server</a>.</p>
<h2>Experiments</h2>
<ul>
<li><p>Let's add a new controller method to <code>PhoneDetailCtrl</code>:</p>
<pre><code> $scope.hello = function(name) {
alert('Hello ' + (name || 'world') + '!');
}
</code></pre>
<p>and add:</p>
<pre><code> <button ng-click="hello('Elmo')">Hello</button>
</code></pre>
<p>to the <code>phone-details.html</code> template.</p></li>
</ul>
<div style="display: none">
TODO!
The controller methods are inherited between controllers/scopes, so you can use the same snippet
in the `phone-list.html` template as well.
* Move the `hello` method from `PhoneCatCtrl` to `PhoneListCtrl` and you'll see that the button
declared in `index.html` will stop working, while the one declared in the `phone-list.html`
template remains operational.
</div>
<h2>Summary</h2>
<p>With the phone image swapper in place, we're ready for <a href="tutorial/step_11">step 11</a> (the last step!) to
learn an even better way to fetch data.</p>
<ul doc-tutorial-nav="10"></ul></div>