在這一步中,你將實(shí)現(xiàn)手機(jī)詳情視圖,當(dāng)用戶(hù)在手機(jī)列表中點(diǎn)擊了一款手機(jī),就會(huì)顯示這個(gè)視圖。
要想實(shí)現(xiàn)手機(jī)詳情視力,我們將使用$http以取回我們的數(shù)據(jù),然后具體化phone-detail.html
視圖模板。
把工作空間重置到第八步
git checkout -f step-8
刷新你的瀏覽器或在線檢查這一步:Step 8 Live Demo
下面列出了第七步和第八步之間最重要的區(qū)別。你可以在GitHub上看到完整的差異。
除了phones.json
,app/phones/
目錄還包括一個(gè)針對(duì)每款手機(jī)的JSON文件:
app/phones/nexus-s.json
: (sample snippet)
{
"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"
}
}
每個(gè)文件用同樣的數(shù)據(jù)結(jié)構(gòu)描述了手機(jī)的多種屬性。我們將在手機(jī)詳情視圖中展示這些數(shù)據(jù)。
我們將使用$http
服務(wù)以擴(kuò)展PhoneDetailCtrl
,從而取回JSON文件。這以手機(jī)列表控制器中同樣的方式起作用。
app/js/controllers.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;
});
}]);
要想為HTTP請(qǐng)求構(gòu)造URL,我們使用從$route
服務(wù)生成的當(dāng)前路由中提取到的$routeParames.phoneId
。
該TBD占位符行已經(jīng)被替換成列表,綁定包含了手機(jī)詳情。注意我們使用Angular的{{expression}}
標(biāo)簽以及ngRepeat
的地方,用來(lái)從我們的模塊把投射手機(jī)數(shù)據(jù)到視圖中。
app/partials/phone-detail.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>
我們寫(xiě)了一個(gè)新的單元測(cè)試,類(lèi)似于我們之前在第五步中為PhoneListCtrl
控制器所寫(xiě)的步驟。
test/unit/controllersSpec.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'});
});
});
...
你現(xiàn)在可以看到后來(lái)在Karma標(biāo)簽中的輸出:
Chrome 22.0: Executed 3 of 3 SUCCESS (0.039 secs / 0.012 secs)
我們還添加了一個(gè)新的端到端的測(cè)試,導(dǎo)航到Nexus S詳情頁(yè)面,并核查了頁(yè)面上的標(biāo)題是“Nexus S”。
test/e2e/scenarios.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');
});
});
...
你可以再次運(yùn)行npm run protractor
以看到測(cè)試運(yùn)行。
現(xiàn)在手機(jī)詳情視力已經(jīng)到位了,繼續(xù)前往第九步 篩選器以學(xué)習(xí)如何編寫(xiě)你自己的自定義顯示過(guò)濾器。
更多建議: