在这一步中,我们会对手机图片添加点击支持,点击后会在手机详细说明页面显示新的图形。
直接用浏览器访问步骤10在线演示
大多数的重要改变都会列在下面,不过你也可以在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
控制器中,我们创建了一个mainImageUrl
模型属性,并且设置默认值为第一个手机图片的URL。
我们也创建可一个setImage
的行为处理函数,来改变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
绑定到大图片的URL。
我们也为缩略图注册了ngClick
处理,当用户点击任何缩略图的时候进行处理,这个处理会使用setImage
行为处理函数依据点击的缩略图来改变mainImageUrl
的值,从而改变大图显示内容。
为了检测新特性,我们需要写2个端到端测试。其中一个验证手机详细说明页面开始时,主要图(大图)是否是对应显示的第1个手机图片(默认值)。第二个测试检查点击一些缩略图是否会正确进行图片切换。
test/e2e/secnarios.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/);
});
});
我们现在可以运行npm run protractor
来完成测试了。
你也可以重构单元测试,因为这一步添加了mainImageUrl
模型到PhoneDetailCtrl
控制器中。下面,我们创建一个叫xyzPhoneData
的函数,它会返回images
属性的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());
});
});
现在单元测试能通过了。
让我们给PhoneDetailCtrl
添加新的方法:
$scope.hello = function(name) {
alert('Hello ' + (name || 'world') + '!');
}
并把
<button ng-click="hello('Elmo')">Hello</button>
添加到`phone-detail.html`模板中。
我们的手机图片已经可以在指定位置进行切换了,我们准备进入步骤11来学习一个更好的获取数据的方法。