代码之家  ›  专栏  ›  技术社区  ›  Nishant Florentin

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

  •  0
  • Nishant Florentin  · 技术社区  · 6 年前

    假设有一个这样的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 回复  |  直到 6 年前
        1
  •  2
  •   Nishant Florentin    6 年前

    1。

    $interval(f, time)
    

    或多或少

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

    2。

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

    或多或少

    $scope.$watch('test', function(value) {
      divElement.innerHTML = value;
    })
    
        2
  •  1
  •   Nishant Florentin    6 年前

    为什么会这样?是 $interval 做点魔术?

    是的,是的。它正在自动触发 AngularJS digest cycle ,您可以用“手动”操作 $scope.$apply() (这也会触发它)。这会导致更改反映在DOM中。如果不触发摘要循环,则AngularJS“不知道模型中有更改,因此它不会更新DOM”。

    (…)我不需要观察这些变量吗?

    没有,除非您需要在这些变量中的任何一个改变了它们的值时得到通知。只要在AngularJS范围内进行所有更改,就会始终“通知”(更新)DOM。

    如何知道我什么时候在安古拉吉斯范围内做这件事?

    通常在使用服务提供的功能时,例如 $interval $timeout 你在做范围内的事情,因为这些是原始的包装纸( setInterval setTimeout )并自动触发上述的摘要循环,使模型和DOM之间保持同步。

    所以, 最后 ,

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

    因为在控制台中,您正在进行AngularJS范围之外的一些更改,需要自己触发所提到的消化循环。