forked from angular/code.angularjs.org
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstep_08.html
152 lines (127 loc) · 5.9 KB
/
step_08.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<a href='http://github.com/angular/angular.js/edit/master/docs/content/tutorial/step_08.ngdoc' class='improve-docs btn btn-primary'><i class="glyphicon glyphicon-edit"> </i>Improve this doc</a>
<ul doc-tutorial-nav="8"></ul>
<p>In this step, you will implement the phone details view, which is displayed when a user clicks on a
phone in the phone list.</p>
<ul>
<li>When you click on a phone on the list, the phone details page with phone-specific information
is displayed.</li>
</ul>
<p>To implement the phone details view we used <a href="api/ng/service/$http">$http</a> to fetch our data, and we
fleshed out the <code>phone-detail.html</code> view template.</p>
<div doc-tutorial-reset="8"></div>
<h2 id="data">Data</h2>
<p>In addition to <code>phones.json</code>, the <code>app/phones/</code> directory also contains one json file for each
phone:</p>
<p><strong><code>app/phones/nexus-s.json</code>:</strong> (sample snippet)</p>
<pre><code class="lang-js">{
"additionalFeatures": "Contour Display, Near Field Communications (NFC),...",
"android": {
"os": "Android 2.3",
"ui": "Android"
},
...
"images": [
"img/phones/nexus-s.0.jpg",
"img/phones/nexus-s.1.jpg",
"img/phones/nexus-s.2.jpg",
"img/phones/nexus-s.3.jpg"
],
"storage": {
"flash": "16384MB",
"ram": "512MB"
}
}</code></pre>
<p>Each of these files describes various properties of the phone using the same data structure. We'll
show this data in the phone detail view.</p>
<h2 id="controller">Controller</h2>
<p>We'll expand the <code>PhoneDetailCtrl</code> by using the <code>$http</code> service to fetch the json files. This works
the same way as the phone list controller.</p>
<p><strong><code>app/js/controllers.js</code>:</strong></p>
<pre><code class="lang-js">var phonecatControllers = angular.module('phonecatControllers',[]);
phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
$http.get('phones/' + $routeParams.phoneId + '.json').success(function(data) {
$scope.phone = data;
});
}]);</code></pre>
<p>To construct the URL for the HTTP request, we use <code>$routeParams.phoneId</code> extracted from the current
route by the <code>$route</code> service.</p>
<h2 id="template">Template</h2>
<p>The TBD placeholder line has been replaced with lists and bindings that comprise the phone details.
Note where we use the Angular <code>{{expression}}</code> markup and <code>ngRepeat</code> to project phone data from
our model into the view.</p>
<p><strong><code>app/partials/phone-detail.html</code>:</strong></p>
<pre><code class="lang-html"><img ng-src="{{phone.images[0]}}" 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}}">
</li>
</ul>
<ul class="specs">
<li>
<span>Availability and Networks</span>
<dl>
<dt>Availability</dt>
<dd ng-repeat="availability in phone.availability">{{availability}}</dd>
</dl>
</li>
...
<li>
<span>Additional Features</span>
<dd>{{phone.additionalFeatures}}</dd>
</li>
</ul></code></pre>
<div style="display: none">
TODO!
<img class="diagram" src="img/tutorial/tutorial_08-09_final.png">
</div>
<h2 id="test">Test</h2>
<p>We wrote a new unit test that is similar to the one we wrote for the <code>PhoneListCtrl</code> controller in
step 5.</p>
<p><strong><code>test/unit/controllersSpec.js</code>:</strong></p>
<pre><code class="lang-js">
beforeEach(module('phonecatApp'));
...
describe('PhoneDetailCtrl', function(){
var scope, $httpBackend, ctrl;
beforeEach(inject(function(_$httpBackend_, $rootScope, $routeParams, $controller) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('phones/xyz.json').respond({name:'phone xyz'});
$routeParams.phoneId = 'xyz';
scope = $rootScope.$new();
ctrl = $controller('PhoneDetailCtrl', {$scope: scope});
}));
it('should fetch phone detail', function() {
expect(scope.phone).toBeUndefined();
$httpBackend.flush();
expect(scope.phone).toEqual({name:'phone xyz'});
});
});
...</code></pre>
<p>You should now see the following output in the Karma tab:</p>
<pre>Chrome 22.0: Executed 3 of 3 SUCCESS (0.039 secs / 0.012 secs)</pre>
<p>We also added a new end-to-end test that navigates to the Nexus S detail page and verifies that the
heading on the page is "Nexus S".</p>
<p><strong><code>test/e2e/scenarios.js</code>:</strong></p>
<pre><code class="lang-js">...
describe('Phone detail view', function() {
beforeEach(function() {
browser.get('app/index.html#/phones/nexus-s');
});
it('should display nexus-s page', function() {
expect(element(by.binding('phone.name')).getText()).toBe('Nexus S');
});
});
...</code></pre>
<p>You can now rerun <code>npm run protractor</code> to see the tests run.</p>
<h1 id="experiments">Experiments</h1>
<ul>
<li>Using the <a href="https://github.com/angular/protractor/blob/master/docs/api.md">Protractor API</a>,
write a test that verifies that we display 4 thumbnail images on the Nexus S details page.</li>
</ul>
<h1 id="summary">Summary</h1>
<p>Now that the phone details view is in place, proceed to <a href="tutorial/step_09">step 9</a> to learn how to
write your own custom display filter.</p>
<ul doc-tutorial-nav="8"></ul>