angularjs的apply的使用

1. AngularJS的双向数据绑定,使model变更都会被反映到view中。对于检查绑定的数据到底有没有发生变化,实际上是由scope.digest()完成的,但是我们几乎从来就没有直接调用过这个方法,而是调用scope.apply()方法,是因为在scope.apply()方法里面,它会去调用scope.digest()方法。scope.apply()方法带一个函数或者一个表达式,然后执行它,最后调用scope.digest()方法去更新bindings或者watchers。除了ng-click指令,还有一些其它的built-in指令以及服务来让你更改models(比如ng-model$timeout)和自动触发一次$digest循环.

2. $scope.$apply()会自动地调用$rootScope.$digest()$apply()方法有两种形式。

第一种会接受一个function作为参数,执行该function并且触发一轮$digest循环。

第二种会不接受任何参数,只是触发一轮$digest循环。

3. 但是,如果你在AngularJS上下文之外的任何地方修改了model,那么你就需要通过手动调用$apply()来通知AngularJS

比如,如果你使用了JavaScript中的setTimeout()来更新一个scope model,那么AngularJS就没有办法知道你更改了什么.调用$apply()就是你的责任了,通过调用它来触发一轮$digest循环。

我们不应该这样做,而是用angular JS提供的timeout方法,这样它就会被自动用apply方法包起来了。

方式1"
$scope.getMessage = function() { 
  setTimeout(function() { 
    $scope.$apply(function() { 
      //wrapped this within $apply 
      $scope.message = 'Fetched after 3 seconds'; 
      console.log('message:' + $scope.message); 
    }); 
  }, 2000); 
}

方式2:
$scope.getMessage = function() { 
  setTimeout(function() { 
    $scope.message = 'Fetched after two seconds'; 
    console.log('message:' + $scope.message); 
    $scope.$apply(); //this triggers a $digest 
  }, 2000); 
};
方式3:
$timeout.cancel(scope.t2);
   scope.t1 = $timeout(function(){
   scope.ifShowMenu = true
},500)

类似地,如果你有一个指令用来设置一个DOM事件listener并且在该listener中修改了一些models,那么你也需要通过手动调用$apply()来确保变更会被正确的反映到view中。 

4. Scope提供$watch方法监视Model的变化。
    Scope提供$apply方法传播Model的变化。
    Scope可以继承,用来隔离不同的application components和属性访问权限。
    Scope为Expressions的计算提供上下文。

5. 还是那个问题,那我们到底什么时候需要去调用apply()方法呢?情况非常少,实际上几乎我们所有的代码都包在scope.apply()里面,像ng−click,controller的初始化,http的回调函数等。在这些情况下,我们不需要自己调用,实际上我们也不能自己调用,否则在apply()方法里面再调用apply()方法会抛出错误。

   如果我们需要在一个新的执行序列中运行代码时才真正需要用到它,而且当且仅当这个新的执行序列不是被angular JS的库的方法创建的,这个时候我们需要将代码用scope.apply()包起来。

原文地址:https://www.cnblogs.com/floraCnblogs/p/angular-scope-apply.html