为什么在$ document.keydown()中需要范围。$ digest()?

时间:2014-07-02 00:47:20

标签: angularjs

我有一个幻灯片服务:

app.factory('slideDeckService', function () {
    var slideDeck = new SlideDeck();

    return {
      currentPosition: 0,
      ...

      back: function () { // Back to last slide
        if(this.currentPosition > 0) {
          this.currentPosition--;
        }
      },

      forward: function () { // Advance to next slide
        if(this.currentPosition < slideDeck.slides.length - 1) {
          this.currentPosition++;
        }
      }
    }
  });

我将服务注入此指令:

app.directive('coreSlides', [ 
    'slideDeckService', 
    '$document',
    '$log',

    function(slideDeckService, $document, $log) {
      return {
        restrict: 'E',
        templateUrl: 'views/partials/slides-template.html',
        transclude: true,

        controller: function ($scope) {
          $document.keydown(function(event) {
            var LEFT_ARROW = 37, RIGHT_ARROW = 39;

            if(event.keyCode === RIGHT_ARROW) {
              slideDeckService.forward();
            }
            else if(event.keyCode === LEFT_ARROW) {
              slideDeckService.back();
            }
          });

          $scope.$watch(
            function () { return slideDeckService.currentPosition; },

            function(newValue, oldValue) {
              $log.info('new value: ' + newValue + ', 
                         old value: ' + oldValue);
            });
        },

        link: function (scope, el, attrs) { ... }
     }
  }]);

但这不起作用。对于$ scope。$ watch()工作我必须显式调用$ scope。$ digest(),如下所示:

$document.keydown(function(event) {
  var LEFT_ARROW = 37, RIGHT_ARROW = 39;
  var forward = event.keyCode != 37;  // left arrow goes back

  if(event.keyCode === RIGHT_ARROW) {
    slideDeckService.forward();
    $scope.$digest();  // Why is this necessary?
  }
  else if(event.keyCode === LEFT_ARROW) {
    slideDeckService.back();
    $scope.$digest(); // Why is this necessary?
  }
  ...
});

我的印象是,像$ document这样的注入对象主要存在于必要时运行$ digest()方法。我希望$ document.keydown()在完成时自动调用$ scope。$ digest()。在$ document.keydown()里面我不是在Angular领域?如果我使用普通的旧文档对象,我希望必须调用$ digest(),但我不希望使用$ document。

我真的很感激,如果有人能够解释为什么在这种情况下显式调用$ scope。$ digest()是必要的。感谢。

1 个答案:

答案 0 :(得分:0)

documentation表示$document只是一个JQuery / JQLite包装器,当用户触发事件时你不在$ digest-loop中,并且没有任何内容自动,将导致循环发生。

Angular自己的内置指令触发用户事件也必须触发$ digest-loops via $apply