为什么在从控制台进行更改时我们需要$ scope.apply()而不是其他?

时间:2018-05-25 15:56:45

标签: angularjs data-binding

假设有一个像这样的AngularJS控制器:

var module = angular.module('myApp', []);

module.controller('TimeCtrl', function($scope, $interval) {
  var tick = function() {
    $scope.clock = Date.now();
    window.scope = $scope;
  }
  tick();
  $interval(tick, 1000);
});
  1. 更改$scope.clock会自动反映在DOM中。 但是,当我在控制台中执行此操作时,我需要明确地执行此操作 $scope.apply。为什么会这样? $interval是否有些神奇?
  2. 一般来说,我不需要$scope.watch这些变量吗?我认为$scope.watch的目的是这个。

2 个答案:

答案 0 :(得分:2)

1

$interval(f, time)

或多或少

setInterval(function() {
   f();
   $rootScope.$apply();
}, time)

2

<div>{{test}}</div>

或多或少

$scope.$watch('test', function(value) {
  divElement.innerHTML = value;
})

答案 1 :(得分:1)

  

为什么会这样? $interval做了一些魔术吗?

是的,确实如此。它会自动触发AngularJS digest cycle,这是您使用$scope.$apply()“手动”执行的操作(也会触发它)。这会导致更改反映在DOM中。如果没有触发摘要周期,AngularJS“不知道模型中已经进行了更改,因此它不会更新DOM”。

  

(...)我不需要看这些变量吗?

不,除非您需要在任何这些变量更改其值时收到通知。只要您在AngularJS范围内进行所有更改,DOM将始终被“通知”(更新)。

如何知道我在AngularJS范围内做什么?

通常当您使用$interval$timeout等服务提供的功能时,您在范围内做事,因为它们是原始(setInterval和{{的包装器3}})并自动触发提到的摘要周期,保持模型和DOM之间的同步。

所以,终于

  

为什么我们在从控制台进行更改时需要$scope.apply(),而不是   否则?

因为从控制台你在AngularJS范围之外做了一些更改,需要自己触发提到的摘要周期。