我有一个 UI 组件,$watch
它的宽度有回调(原因与这篇文章无关)。问题是在某些情况下:
- 宽度从非角度上下文改变->
- 没有
$digest
循环-> - 我的
$watch
回调没有被调用。
尽管我的应用程序是一个完整的 Angular 应用程序,但仍然存在代码在非 Angular 上下文中执行的情况。例如:JQuery 调用window.setTimeout
- 所以即使我的代码JQuery
是从角度上下文中调用的,超时回调也会在非角度上下文中调用,并且$watch
之后不会执行我的回调。
顺便说一句,即使是棱角分明的自己也会打电话给window.setTimeout
他们AnimatorService
......
所以我的问题是:如何确保在$digest
执行任何代码后始终执行循环?(即使代码是第 3 方代码......)
我考虑过覆盖原始window.setTimeout
方法,但是:
- 感觉有点丑陋和危险。
- 恐怕它不会涵盖所有用例。
添加一个plunker。plunker 样本包含:
- 可以使用 JQuery
fadeOut
方法隐藏的元素。 - 执行
fadeOut
隐藏元素调用的按钮。 - 显示元素显示状态的文本(
Shown!!!
或Hidden!!!
)。此文本通过$watch
对元素display
属性进行 ing 更新。 - 一个按钮,除了启动一些角度代码之外什么都不做,以便
$digest
调用一个循环。
流动:
- 单击
Fade Out
按钮 -> 元素将被隐藏但状态文本将保留Shown!!!
。您现在可以永远等待 - 或者: - 单击
Do Nothing
按钮-> 文本会突然改变。
为什么?
单击Fade Out
按钮时JQuery.fadeOut
调用该window.setTimeout
方法。之后我的$watch
回调被调用,但元素仍然没有隐藏。该元素仅在调用超时回调后才隐藏 - 但是没有$digest
循环(而且我无法知道触发一个)。只有在下次运行角度代码时,我的$watch
函数才会被再次调用并且状态会被更新。