AngularJs中$scope.$apply()方法总结

目录

功能

  $apply()函数可以从Angular框架的外部让表达式在Angular上下文内部执行。例如,假设你实现了一个setTimeout()或者使用第三方库并且想让事件运行在Angular上下文内部时,就必须使用$apply()。


参数

  $apply()函数接受一个可选的参数。这个表达式可选地接受一个字符串或函数,并且是在当前作用域内执行。如果传入一个字符串,$apply()首先会在这个字符串上调用$eval(),以强制Angular在局部作用域上下文中使用$eval()运行字符串表达式。如果传入一个函数,这个函数将会在所传入的函数作用域上执行。$exceptionHandler服务会捕获和处理$eval()方法抛出的所有异常。最后,$apply()方法还会直接调用$digest循环。


示例一

1
2
3
4
5
6
7
8
9
10
11
12
13
// 使用要eval的字符串调用$apply示例
$scope.$apply('message = "Hello World"');
// 使用函数的方式并给函数传入一个作用域
$scope.apply(function(scope) {
// 然后在函数中使用传入作用域
$scope.message = "Hello World";
});
// 使用函数时忽略作用域
$scope.$apply(function() {
$scope.message = "Hello World";
});
// 或者通过在操作的尾部调用$apply()以强制运行$digest循环
$scope.apply();

示例二

1
2
3
4
5
6
7
functionCtrl($scope) {
$scope.message ="Waiting 2000ms for update";
setTimeout(function () {
  $scope.message ="Timeout called!";
// AngularJS unaware of update to $scope
}, 2000);
}

  上述代码执行完成后,$scope.message仍然是”Waiting 2000ms for update”。原因是setTimeout函数创建了一个闭包,是自己独立的作用域,而这个作用域的变化不能被angular检测感知。
  修改写法如下即可:

1
2
3
4
5
6
7
8
functionCtrl($scope) {
$scope.message ="Waiting 2000ms for update";
setTimeout(function () {
  $scope.$apply(function () {
  $scope.message ="Timeout called!";
});
}, 2000);
}

注意事项

  简而言之,使用$scope.$apply()时可以从外部进入上下文。如果在事件被触发时调用$apply(),就会使用Angular事件循环来运行它。如果没有调用
$apply(),就不会在事件循环内执行这个函数,而它会运行在Angular上下文外部。
  通常可以依赖于Angular提供的可用于视图中的任意指令来调用$apply()。所有ng-[event]指令(比如ng-click、ng-keypress)都会调用$apply()。
此外还可以依赖于一系列Angular内置的服务来调用$digest()。比如$http服务会在XHR请求完成并触发更新返回值(promise)之后调用$apply()。无论何时我们手动处理事件,使用第三方框架(比如jQuery),或者调用setTimeout(),都可以使用$apply()函数让Angular返回$digest循环。
  当我们将jQuery和Angular集成在一起时(并非最佳实践),就需要使用$apply(),因为Angular不会察觉到执行在Angular上下文外部的事件。例如,在使用jQuery插件
时(比如datepicker),就需要使用$apply()将来自jQuery的值传递到Angular应用中。