当前位置: 首页 > 面试题库 >

角度$ scope。$ apply与$ timeout作为安全的$ apply

唐炜
2023-03-14
问题内容

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

据我了解:

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

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

  1. 如果摘要周期已经在进行中,为什么$ timeout()也不会引发错误?
  2. 当您确定摘要尚未进行时,使用$ scope。$ apply()是最佳实践吗?当需要使用任一方法来确保其安全性时,是使用$ timeout()吗?
  3. 是$ timeout()确实可以接受的“安全应用”,还是有陷阱?

感谢您的任何见解。


问题答案:

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

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

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

  • 当您确定摘要尚未进行时,使用$ scope。$ apply()是最佳实践吗?当需要使用任一方法来确保其安全性时,是使用$ timeout()吗?

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

  • 是$ timeout()确实可以接受的“安全应用”,还是有陷阱?

它应该总是安全的,但是我认为您的go方法应该始终以$ apply()为目标。我正在使用的当前Angular应用程序相当大,我们只需要依赖$
timeout一次,而不是$ apply()。



 类似资料:
  • 问题内容: 我只想知道火热的使用方法。在控制器内,以下代码可以正常工作,并且在3秒后更新DOM: 但是通过使用 没发生什么事… 我以为他们做同样的事情。我怎么了? 问题答案: 并有一些异同。它们的相似之处在于它们都检查了更改内容并更新了UI并触发了所有观察程序。 两者之间的区别是它们的调用方式。被调用而没有任何参数。具有在执行任何更新之前将要执行的功能。 另一个区别是它们的影响。将更新当前范围和任

  • 问题内容: 我想标题很清楚我要问的内容。我创建了这个小提琴:http : //jsfiddle.net/Sourabh_/HB7LU/13142/ 在小提琴中,我试图复制一个场景。这只是一个示例,但是在AJAX调用中,如果我不使用该列表,则不会更新。我想知道每次进行AJAX调用来更新列表时是否可以安全使用?是否可以使用其他机制? 我编写的用于复制场景的代码(与小提琴相同): 的HTML JS 问题

  • 问题内容: 当我通过Angular应用中的websocket接收数据时,我一直在使用它来更新模型的绑定。但是它实际上是做什么的,为什么需要调用它才能完成更新? 问题答案: 从Angular文档: $ apply()用于从角度框架外部以角度执行表达式。(例如,来自浏览器DOM事件,setTimeout,XHR或第三方库)。因为我们正在调用角度框架,所以我们需要执行异常处理的适当范围生命周期,并执行监

  • 问题内容: 有时我需要在代码中使用它,有时它会引发“已消化的摘要”错误。但是,您可以在评论中(以及在Angular Wiki上)阅读: 如果(!$ scope。$$ phase)$ scope。$ apply()不要这样做,这意味着您的$ scope。$ apply()在调用堆栈中不够高。 所以现在我有两个问题: 为什么这是反模式? 我如何安全地使用$ scope。$ apply? 另一个防止“已

  • 有时我需要在代码中使用,有时它会引发“摘要已经在进行中”错误。因此,我开始寻找解决这个问题的方法,并发现这个问题:AngularJS:prevention error$digest在调用$scope.$apply()时已经在进行。然而,在评论中(以及有棱角的wiki上),您可以读到: 如果(!$scope.$$phase)$scope.$apply(),则不要这样做,这意味着您的$scope.$a

  • 问题内容: 我试图开始使用angular 2.0,现在我想知道在某些外部事件更改数据后如何启动视图更新。 详细来说,我有一个Google地图和一个用于地图上单击事件的处理程序。用户单击地图后,我将单击的纬度和经度存储到控制器上的变量中 在视图中,我想显示这些值 在角度1中,我只需在对$ scope。$ apply()的调用中将分配包装在控制器中即可。 在Angluar 2.0中更新视图的首选方法是