在这一步中,你将添加一个可点击的手机图像交换器,指向手机详情页面。
把工作空间重置到第十步
git checkout -f step-10
刷新你的浏览器或在线检查这一步:Step 10 Live Demo
下面列出了第九步和第十步之间最重要的区别。你可以在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
属性上。
我们还将利用缩略图注册一个ngClick
处理函数。当用户在缩图略之一上点击时,处理函数将使用setImage
事件处理函数以改变mainImageUrl
属性的值,把它变成缩略图的URL。
要想验证这个功能,我们添加了两个端到端测试。一个验证了主图像被默认设置为每一个手机图像。另一个测试了在一些缩略图上的点击,并验证了相应的主图像改变。
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/);
});
});
现在你可以再次运行rpn run protractor
以看到测试运行。
你还必须重构你的单元测试之一,因为又有一个mainImageUrl
模块属性添加到了PhoneDetailCtrl
控制器上了。下面,我们创建了函数xyzPhoneData
,该函数会返回相应的带有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());
});
});
你的单元测试现在应该通过了。
让我们给PhoneDetailCtrl
添加一个新的控制器方法:
$scope.hello = function(name) {
alert("Hello " + (name || "world") + "!");
}
再添加
<button ng-click="hello("Elmo")">Hello</button>
to the phone-detail.html
template.
随着手机图像交换器到位,我们准备前往第十一步 REST和自定义服务以学习取得数据的一个更好方法。
使用命令在一个 Vue CLI 项目中,@vue/cli-service安装了一个名为vue-cli-service的命令。你可以在 npm scripts 中以vue-cli-ser...
描述@for指令使用关键字,指定从start值到end值之前的值的范围。语句@for $var from start to end下面简要解释语法。$var: 它表...
描述LESS中的颜色定义函数使定义和操作颜色变得超级简单,使用颜色函数可以帮助你控制颜色、更好地配色。LESS提供了许多有用的颜...
UI /主题框架和组件LESS支持下表中列出的一些UI /主题框架:S.N.框架和描述11pxdeep 它是平的Bootstrap 3主题,提供强大的配色方...
如今我们的网站、页面更加需要注重细节,不论是字体的样式、还是图片的分辨率清晰度都会影响到用户的访问体验和 PV,以及用户以...