本文介绍了Angular $scope.$apply 与 $timeout 作为安全的 $apply的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更好地理解在 Angular 中使用 $timeout 服务作为一种安全的 $apply"方法的细微差别.基本上是在一段代码可以运行以响应 Angular 事件或非 Angular 事件(例如 jQuery 或某些标准 DOM 事件)的情况下.

I'm trying to better understand the nuances of using the $timeout service in Angular as a sort of "safe $apply" method. Basically in scenarios where a piece of code could run in response to either an Angular event or a non-angular event such as jQuery or some standard DOM event.

据我所知:

  1. 在 $scope.$apply 中包装代码适用于以下情况尚未处于摘要循环中(又名 jQuery 事件),但如果摘要正在进行,则会引发错误
  2. 在没有延迟参数的 $timeout() 调用中包装代码无论是否已经在摘要循环中都有效

查看 Angular 源代码,看起来 $timeout 调用了 $rootScope.$apply().

Looking at Angular source code, it looks like $timeout makes a call to $rootScope.$apply().

  1. 如果摘要循环已经在进行中,为什么 $timeout() 也不会引发错误?
  2. 当您确定摘要不会在进行中时使用 $scope.$apply() 时使用 $timeout() 以确保安全时使用 $timeout() 是最佳做法吗?
  3. $timeout() 真的是可以接受的安全申请",还是有问题?

感谢您的任何见解.

推荐答案

  • 如果摘要循环已经在进行中,为什么 $timeout() 也不会引发错误?

$timeout 使用未记录的 Angular 服务 $browser.具体来说,它使用 $browser.defer() 通过 window.setTimeout(fn, delay) 异步延迟函数的执行,这将始终在 Angular 生命周期之外运行.只有在 window.setTimeout 触发后,您的函数才会 $timeout 调用 $rootScope.$apply().

$timeout makes use of an undocumented Angular service $browser. Specifically it uses $browser.defer() that defers execution of your function asynchronously via window.setTimeout(fn, delay), which will always run outside of Angular life-cycle. Only once window.setTimeout has fired your function will $timeout call $rootScope.$apply().

  • 当您确定摘要不会在进行中时使用 $scope.$apply() 时使用 $timeout() 以确保安全时使用 $timeout() 是最佳做法吗?

我会这么说.另一个用例是有时您需要访问 $scope 变量,您知道该变量只会在摘要后初始化.简单的例子是,如果您想在控制器构造函数中将表单的状态设置为脏状态(无论出于何种原因).如果没有 $timeout,FormController 还没有被初始化并发布到 $scope 上,所以将 $scope.yourform.setDirty() 包裹在 $timeout 中可以确保 FormController 已初始化.当然,您可以使用不带 $timeout 的指令完成所有这些操作,只需提供另一个用例示例.

I would say so. Another use case is that sometimes you need to access a $scope variable that you know will only be initialized after digest. Simple example would be if you want to set a form's state to dirty inside your controller constructor (for whatever reason). Without $timeout the FormController has not been initialized and published onto $scope, so wrapping $scope.yourform.setDirty() inside $timeout ensures that FormController has been initialized. Sure you can do all this with a directive without $timeout, just giving another use case example.

  • $timeout() 真的是可以接受的安全应用",还是有问题?

它应该始终是安全的,但在我看来,您的 go to 方法应该始终针对 $apply().我正在开发的当前 Angular 应用程序相当大,我们只需要依赖 $timeout 一次而不是 $apply().

It should always be safe, but your go to method should always aim for $apply() in my opinion. The current Angular app I'm working on is fairly large and we've only had to rely on $timeout once instead of $apply().

这篇关于Angular $scope.$apply 与 $timeout 作为安全的 $apply的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 19:24