我正在努力更好地理解将$timeout服务作为一种“安全$apply”方法在角度上使用的细微差别。基本上,在这样的场景中,一段代码可以响应角事件或非角事件(如jQuery或一些标准DOM事件)运行。
据我所知:
查看角源代码,它看起来像是$timeout调用了$rootScope.$apply()。
谢谢你的见解。
发布于 2014-04-15 03:05:32
查看角源代码,它看起来像是$timeout调用了$rootScope.$apply()。
$timeout
使用了无文档化的角服务$browser
。具体来说,它使用$browser.defer()
,它通过window.setTimeout(fn, delay)
异步地推迟函数的执行,而window.setTimeout(fn, delay)
总是在角度生命周期之外运行。只有在window.setTimeout
启动您的函数之后,$timeout
才会调用$rootScope.$apply()
。
我可以这么说。另一个用例是,有时您需要访问一个您知道只有在摘要之后才会初始化的$scope变量。简单的示例是,如果您希望将窗体的状态设置为控制器构造函数中的脏状态(无论出于什么原因)。没有$timeout,FormController
还没有初始化并发布到$scope上,因此将$scope.yourform.setDirty()
封装在$timeout中可以确保FormController
已经初始化。当然,您可以在不使用$timeout的情况下使用指令完成所有这些操作,只需给出另一个用例示例。
它应该始终是安全的,但在我看来,使用方法应该始终以$apply()为目标。我正在开发的当前的角应用程序相当大,我们只需要依赖$timeout一次,而不是$apply()。
发布于 2015-07-27 09:12:33
如果我们在应用程序中大量使用$apply,我们可能会得到错误:$digest已经在进行中。发生这种情况是因为一次可以运行一个$digest循环。我们可以通过$timeout或$evalAsync来解决这个问题。
$timeout不会产生像"$digest已经在进行中“这样的错误,因为$timeout告诉角,在当前周期之后,有一个超时等待,这样可以确保在摘要周期之间不会发生任何冲突,因此$timeout的输出将在一个新的$digest周期上执行。
我试着在:应用、超时、摘要和evalAsync的比较解释他们。
也许它会对你有帮助。
发布于 2014-04-14 22:36:40
据我所知,$timeout
是setTimeout
的包装器,含蓄地称为$scope.$apply
,这意味着它运行在角度生命周期之外,但启动了角度生命周期本身。我能想到的唯一“理解”是,如果您期望您的结果在这个$digest
上可用,那么您需要找到另一种“安全应用”的方法( AFAIK只能通过$scope.$$phase
获得)。
https://stackoverflow.com/questions/23070822
复制相似问题