Angular $ scope.$ apply vs $ timeout作为安全$ apply

bin*_*les 68 scope angularjs

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

据我所知:

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

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

  1. 如果摘要周期已在进行中,为什么$ timeout()也不会引发错误?
  2. 最好的做法是使用$ scope.$ apply()当你确定一个摘要不会在进行中时和$ timeout()当需要它是安全的时候?
  3. $ timeout()真的是一个可以接受的"安全申请",还是有问题?

感谢您的任何见解.

Bey*_*ers 62

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

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

$timeout利用无证角服务$browser.具体来说,它使用$browser.defer()异步通过推迟你的函数的执行window.setTimeout(fn, delay),这将永远在外面跑角生命周期.只有一次window.setTimeout已经解雇你的功能会$timeout打电话$rootScope.$apply().

  • 最好的做法是使用$ scope.$ apply()当你确定一个摘要不会在进行中时和$ timeout()当需要它是安全的时候?

我会这么说的.另一种使用情况是,有时你需要访问你只知道会消化后初始化$范围变量.如果你想设置你的控制器构造(无论何种原因)内部窗体的状态脏简单的例子是.无$超时FormController尚未初始化并发布到$范围,使包装$scope.yourform.setDirty()内部的$超时确保FormController已初始化.当然你可以使用没有$ timeout的指令来完成所有这些,只是给出另一个用例示例.

  • $ timeout()真的是一个可以接受的"安全申请",还是有问题?

它应该永远是安全的,但你转到方法应该总是在我看来瞄准$适用().当前角度应用我的工作是相当大,我们只有依靠$超时一次,而不是$适用().


Rah*_*arg 14

如果我们在应用程序中大量使用$ apply,我们可能会得到Error:$ digest正在进行中.这是因为一次可以运行一个$ digest周期.我们可以通过$ timeout或$ evalAsync来解决它.

$ timeout不会产生"$ digest已在进行中"之类的错误,因为$ timeout告诉Angular在当前周期之后有超时等待,这样它确保了摘要周期之间不会发生任何冲突,从而输出$超时将在新的$ digest循环上执行.

我尝试解释它们:apply,timeout,digest和evalAsync的比较.

可能它会帮助你.