angular 击键观察器未正确更新作用域

angular keystroke watcher not properly updating scope

我正在监视键盘事件,特别是左键、右键和 esc。

每个都绑定到一个函数,该函数在页面的控制器中执行某些范围函数。

按下按键时会调用这些函数,但是,应该在这些函数中更新的范围变量似乎什么也没做。

是否存在范围问题?我将这些打字事件绑定到 body 是否有问题?

angular.element( document.body ).bind('keydown keypress', function (event)
{
  if(event.which === 27) // 27 = esc key
  {
    $scope.toggleSize();
    // $scope.$apply(function() {
    //  $scope.fullscreen = !$scope.fullscreen;
    // });
    console.log('scope', $scope.fullscreen);
    event.preventDefault();
  } else if(event.which === 37) {
    console.log('next');
    $scope.goToNextSection('currentSection', $scope.slides);
  } else if(event.which === 39) {
    console.log('prev');
    $scope.goToPreviousSection('currentSection', $scope.slides);
  }
});

AngularJS 需要知道 jQuery 事件何时发生,以便它可以触发 $digest 循环来更新视图。

angular.element( document.body )
   .bind('keydown keypress', function (event) {
       angular.element( document.body ).scope().$apply(function() {
           if(event.which == 27)
           ... etc ...
       });
   });

Angular 仅在摘要循环运行时更新绑定到范围的内容。大多数情况下,Angular 会自动触发摘要以响应某些事件。如果不是这种情况,您需要自己做。这正是这里发生的事情。

当您使用 jqLite/jQuery 监听 DOM 事件时,您需要告诉 Angular 在您更改范围内的某些内容后触发摘要。为此,只需调用 $apply() 方法:

angular.element( document.body ).bind('keydown keypress', function (event)
{
  if(event.which === 27) // 27 = esc key
  {        
    $scope.$apply(function() {        
      $scope.toggleSize();
    });

    console.log('scope', $scope.fullscreen);
    event.preventDefault();
  } else if(event.which === 37) {
    $scope.$apply(function() {
      $scope.goToNextSection('currentSection', $scope.slides);
    });
    console.log('next');
  } else if(event.which === 39) {        
    $scope.$apply(function() {
      $scope.goToPreviousSection('currentSection', $scope.slides);
    });
    console.log('prev');
  }
});

我建议您阅读更多有关作用域和摘要循环的内容。 Angular 文档本身就是一个 good start.

最后,我不确定您是否正在监听控制器中的 DOM 事件。如果是,您可能应该改用指令。