在這一步中,你將添加一個可點擊的手機圖像交換器,指向手機詳情頁面。
把工作空間重置到第十步
git checkout -f step-10
刷新你的瀏覽器或在線檢查這一步:Step 10 Live Demo
下面列出了第九步和第十步之間最重要的區(qū)別。你可以在GitHub上看到完整的差異。
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;
$scope.mainImageUrl = data.images[0];
});
$scope.setImage = function(imageUrl) {
$scope.mainImageUrl = imageUrl;
};
}]);
在PhoneDetailCtrl
控制器中,我們創(chuàng)建了mainImageUrl
模塊屬性,并把它的默認(rèn)值設(shè)置為第一個手機圖像URL。
我們還創(chuàng)建了一個setImage
事件處理函數(shù),它將改變mainImageUrl
的值。
app/partials/phone-detail.html:
<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>
...
我們把大圖像的ngSrc
指令綁定到mainImageUrl
屬性上。
我們還將利用縮略圖注冊一個ngClick
處理函數(shù)。當(dāng)用戶在縮圖略之一上點擊時,處理函數(shù)將使用setImage
事件處理函數(shù)以改變mainImageUrl
屬性的值,把它變成縮略圖的URL。
要想驗證這個功能,我們添加了兩個端到端測試。一個驗證了主圖像被默認(rèn)設(shè)置為每一個手機圖像。另一個測試了在一些縮略圖上的點擊,并驗證了相應(yīng)的主圖像改變。
test/e2e/scenarios.js:
...
describe('Phone detail view', function() {
...
it('should display the first phone image as the main phone image', function() {
expect(element(by.css('img.phone')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
});
it('should swap main image if a thumbnail image is clicked on', function() {
element(by.css('.phone-thumbs li:nth-child(3) img')).click();
expect(element(by.css('img.phone')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/);
element(by.css('.phone-thumbs li:nth-child(1) img')).click();
expect(element(by.css('img.phone')).getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
});
});
現(xiàn)在你可以再次運行rpn run protractor
以看到測試運行。
你還必須重構(gòu)你的單元測試之一,因為又有一個mainImageUrl
模塊屬性添加到了PhoneDetailCtrl
控制器上了。下面,我們創(chuàng)建了函數(shù)xyzPhoneData
,該函數(shù)會返回相應(yīng)的帶有image
元素屬性的json,從而使測試通過。
test/unit/controllersSpec.js:
...
beforeEach(module('phonecatApp'));
...
describe('PhoneDetailCtrl', function(){
var scope, $httpBackend, ctrl,
xyzPhoneData = function() {
return {
name: 'phone xyz',
images: ['image/url1.png', 'image/url2.png']
}
};
beforeEach(inject(function(_$httpBackend_, $rootScope, $routeParams, $controller) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('phones/xyz.json').respond(xyzPhoneData());
$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(xyzPhoneData());
});
});
你的單元測試現(xiàn)在應(yīng)該通過了。
讓我們給PhoneDetailCtrl
添加一個新的控制器方法:
$scope.hello = function(name) {
alert('Hello ' + (name || 'world') + '!');
}
再添加
<button ng-click="hello('Elmo')">Hello</button>
to the phone-detail.html
template.
隨著手機圖像交換器到位,我們準(zhǔn)備前往第十一步 REST和自定義服務(wù)以學(xué)習(xí)取得數(shù)據(jù)的一個更好方法。
更多建議: