EVOLUTION-MANAGER
Edit File: step_08.html
<a href='https://github.com/angular/angular.js/edit/v1.3.x/docs/content/tutorial/step_08.ngdoc?message=docs(tutorial%2F8 - More Templating)%3A%20describe%20your%20change...' 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="http://angular.github.io/protractor/#/api">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>