10-事件处理器

在这一步,你将给手机详细页面增加一个手机图片交换器。

  • 手机详细视图显示一个当前手机大的图片和一系列小的缩略图,如果我们只要直接点击我们所需的缩略图来替换在的图片,那将十分有趣。让我们看看我们能用Angular怎么做。

工作空间重置介绍 重置你的工作区间到第十步

git checkout -f step-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;
    }
  }]);

PhoneDetaialCtrl控制器中,我们创建了一个 mianImageUrl模型属性,设定他的默认值为第一个手机的图片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/);
    });
  });

你可以重新运行 npm run protractor 去看测试结果 你也可以重构你其中了一个单元测试,因为mainImageUrl模型增加了一个属性到 PhoneDetaialCtrl控制器中。下面,我们创建一个函数 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());
    });
  });

你的单元测试现在会通过

实验

让我们给 PhoneDetaialCtrl增加一个新的控制器

$scope.hello = function(name) {
    alert('Hello ' + (name || 'world') + '!');
}

并增加

<button ng-click="hello('Elmo')">Hello</button>

phone-detail.html模板。

总结

在这是使用手机图片交换器,我们已经准备去 11步,学习更好的方法取数据。 原文地址: https://docs.angularjs.org/tutorial/step_10

你可能感兴趣的:(10-事件处理器)