我试图更好地理解在 Angular 中使用 $timeout 服务作为一种“安全 $apply”方法的细微差别。基本上在一段代码可以运行以响应 Angular 事件或非 Angular 事件(例如 jQuery 或某些标准 DOM 事件)的场景中。
据我了解:
- 将代码包装在 $scope.$apply 中适用于您的场景 尚未处于摘要循环(又名 jQuery 事件)中,但如果正在进行摘要,则会引发错误
- 无论是否已处于摘要循环中,在不带延迟参数的 $timeout() 调用中包装代码都有效
查看 Angular 源代码,看起来 $timeout 调用了 $rootScope.$apply()。
- 如果摘要周期已经在进行中,为什么 $timeout() 不会引发错误?
- 当您确定摘要不会正在进行时,最佳做法是使用 $scope.$apply() ,而当需要确保摘要安全时,最佳做法是使用 $timeout() 吗?
- $timeout() 真的是一个可以接受的“安全应用”吗?还是有陷阱?
感谢您的见解。
最佳答案
Looking at Angular source code, it looks like $timeout makes a call to $rootScope.$apply().
- Why doesn't $timeout() also raise an error if a digest cycle is already in progress?
$timeout
使用未记录的 Angular 服务 $browser
。具体来说,它使用 $browser.defer()
通过 window.setTimeout(fn, delay)
异步推迟函数的执行,它将始终在 Angular 生命周期之外运行。仅一次window.setTimeout
已触发您的函数将 $timeout
调用$rootScope.$apply()
.
- Is the best practice to use $scope.$apply() when you know for sure that a digest won't already be in progress and $timeout() when needing it to be safe either way?
我会这么说。另一个用例是,有时您需要访问 $scope 变量,您知道该变量只会在摘要后初始化。简单的例子是,如果您想在 Controller 构造函数内将表单的状态设置为脏(无论出于何种原因)。如果没有 $timeout FormController
尚未初始化并发布到 $scope,因此包装 $scope.yourform.setDirty()
$timeout 内确保 FormController
已初始化。当然,您可以使用没有 $timeout 的指令来完成所有这些操作,只是给出另一个用例示例。
- Is $timeout() really an acceptable "safe apply", or are there gotchas?
它应该始终是安全的,但在我看来,您的 go to 方法应该始终以 $apply() 为目标。我当前正在开发的 Angular 应用程序相当大,我们只需要依赖 $timeout 一次,而不是 $apply()。
关于angularjs - Angular $scope.$apply 与 $timeout 作为安全的 $apply,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23070822/