Do NOT randomly sprinkle it throughout your code. If you are doing
if (!$scope.$$phase) $scope.$apply() it's because you are not high enough in the call stack.
最好不要用 $$phase
正确的方式是:
$timeout(function() {
// anything you want can go here and will safely be run on the next digest.
})
或者
$scope.$evalAsync(function(){
// ....
})
你应该知道的一些细节:
$$phase is private to the framework and there are good reasons for that.
$timeout(callback) will wait until the current digest cycle (if any) is done, then execute the callback, then run at the end a full $apply.
$timeout(callback, delay, false) will do the same (with an optional delay before executing the callback), but will not fire an $apply (third argument) which saves performances if you didn't modify your Angular model ($scope).
$scope.$apply(callback) invokes, among other things, $rootScope.$digest, which means it will redigest the root scope of the application and all of its children, even if you're within an isolated scope.
$scope.$digest() will simply sync its model to the view, but will not digest its parents scope, which can save a lot of performances when working on an isolated part of your HTML with an isolated scope (from a directive mostly). $digest does not take a callback: you execute the code, then digest.
$scope.$evalAsync(callback) has been introduced with angularjs 1.2, and will probably solve most of your troubles.
if you get the $digest already in progress error, then your architecture is wrong: either you don't need to redigest your scope, or you should not be in charge of that.
在使用Angular的时候避免不了经常手动更新作用域的情况,特别是在指令中。通常是用 controller 和 directives 的
$apply()
来手动触发$digest
的。不过直接用它的话,有一定机率会在控制台抛出错误:很多第三方指令中,包括 ui-event 都是这样写来避免报错的:
但是官方不建议我们这么做 When-to-use-$scope.$apply():
最好不要用
$$phase
正确的方式是:
或者
你应该知道的一些细节:
$$phase
is private to the framework and there are good reasons for that.$timeout(callback)
will wait until the current digest cycle (if any) is done, then execute the callback, then run at the end a full $apply.$timeout(callback, delay, false)
will do the same (with an optional delay before executing the callback), but will not fire an $apply (third argument) which saves performances if you didn't modify your Angular model ($scope).$scope.$apply(callback)
invokes, among other things, $rootScope.$digest, which means it will redigest the root scope of the application and all of its children, even if you're within an isolated scope.$scope.$digest()
will simply sync its model to the view, but will not digest its parents scope, which can save a lot of performances when working on an isolated part of your HTML with an isolated scope (from a directive mostly). $digest does not take a callback: you execute the code, then digest.$scope.$evalAsync(callback)
has been introduced with angularjs 1.2, and will probably solve most of your troubles.$digest already in progress error
, then your architecture is wrong: either you don't need to redigest your scope, or you should not be in charge of that.参考: