本文介绍了为什么$ document.keydown()中必须有scope.$ digest()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有滑梯服务:

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(),如下所示:

But that does not work. For the $scope.$watch() to work I have to explicitly invoke $scope.$digest(), as follows:

$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.

I was under the impression that injected objects like $document exist primarily to run the $digest() method as necessary. I expected $document.keydown() to invoke $scope.$digest() automatically when it was done. Inside of $document.keydown() am I not in the Angular realm? If I was using the plain old document object, I would expect to have to invoke $digest(), but I don't expect that with $document.

如果有人可以阐明为什么在这种情况下必须显式调用$ scope.$ digest(),我将非常感激.谢谢.

I'd really appreciate it if someone could shed some light on why the explicit call to $scope.$digest() is necessary in this case. Thanks.

推荐答案

文档指出 $ document 只是一个JQuery/JQLite包装器,当用户触发事件时,您不在$ digest循环中,并且没有任何自动方法会导致循环发生任何一个.

The documentation states that $document is just a JQuery/JQLite wrapper, you're not in a $digest-loop when the user triggers an event, and there's nothing automatic that will cause a loop to happen either.

在用户事件上触发的Angular自己的内置指令还必须触发$ digest-loops 通过$ apply .

Angular's own built-in directives that trigger on user events also has to trigger $digest-loops via $apply.

这篇关于为什么$ document.keydown()中必须有scope.$ digest()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 18:09