blob: 130b4023280b5eaa754af1b1dbccf7c27b26de4c (
plain)
| 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
 | @workInProgress
@ngdoc overview
@name Tutorial: Step 10
@description
<table id="tutorial_nav">
<tr>
<td id="previous_step">{@link tutorial.step_09 Previous}</td>
<td id="step_result">{@link  http://angular.github.com/angular-phonecat/step-10/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-9...step-10
Code Diff}</td>
<td id="next_step">{@link tutorial.step_11 Next}</td>
</tr>
</table>
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 how we can do this with angular.
__`app/partials/phone-detail.html`:__
<pre>
<img ng:src="{{mainImageUrl}}" class="phone"/>
<h1>{{phone.name}}</h1>
<p>{{phone.description}}</p>
<ul class="phone-thumbs">
  <li ng:repeat="img in phone.images">
    <img ng:src="{{img}}" ng:click="setImage(img)">
  </li>
</ul>
...
</pre>
__`app/js/controllers.js`:__
<pre>
...
function PhoneDetailCtrl($xhr) {
  var self = this;
  $xhr('GET', 'phones/' + self.params.phoneId + '.json', function(code, response) {
    self.phone = response;
    self.mainImageUrl = response.images[0];
  });
  self.setImage = function(imageUrl) {
    self.mainImageUrl = imageUrl;
  }
}
//PhoneDetailCtrl.$inject = ['$xhr'];
</pre>
__`test/e2e/scenarios.js`:__
<pre>
/* jasmine-like end2end tests go here */
...
  describe('Phone detail view', function() {
    beforeEach(function() {
      browser().navigateTo('../../app/index.html#/phones/nexus-s');
    });
    it('should display nexus-s page', function() {
      expect(binding('phone.name')).toBe('Nexus S');
    });
    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>
## Discussion:
Adding the phone image swapping feature is fairly straightforward:
* We defined the `mainImageUrl` model property in the details controller (`PhoneDetailCtrl`) and
set the default value of `mainImageUrl` to the first image in the array of images.
* We created a `setImage` controller method to change `mainImageUrl` to the image clicked on by
the user.
* We registered an `{@link angular.directive.ng:click ng:click}` handler for thumb images to use
the `setImage` controller method.
* We expanded the end-to-end test to verify that our new feature is swapping images correctly.
<table id="tutorial_nav">
<tr>
<td id="previous_step">{@link tutorial.step_09 Previous}</td>
<td id="step_result">{@link  http://angular.github.com/angular-phonecat/step-10/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-9...step-10
Code Diff}</td>
<td id="next_step">{@link tutorial.step_11 Next}</td>
</tr>
</table>
 |