等待在AngularJS /一般javascript中应用更改?

时间:2014-02-07 13:43:10

标签: javascript html5 angularjs browser render

我正在将AngularJS用于某个应用程序,并且在将更改推送到视图时遇到了一些问题。

用例

当我对视图/数据进行重大更新(xhr请求,恢复状态和批次)时,我用一个加载器gif向用户发送了它。我使用一个绑定到img标签的标志(使用ngClass),因此在设置标志时会显示加载程序gif。该标志也用作锁(不是以线程安全的方式,但对于手头的任务来说足够好)。我在启动一个进程时获得了锁(设置标志),并在所有xhr调用的最后一个promise($ q)被解析后释放它。

问题

当我使用HTML5历史记录API恢复数据并从服务器加载数据时(在重新加载,向前或向后),视图可能需要花费大量时间来反映对模型所做的更改。由于我只依赖于http请求的承诺,我的加载器gif在视图(可见)更新之前被隐藏。有没有办法检测用户何时可以看到更改而不是观察模型更改?这可能不再是Angular问题,而是一般的JS问题。

时间线

(1)设置标志 - >

(2)执行xhr /模型更改 - >

(3)释放锁定 - >

(4)AngularJS完成申请 - >

(5)可见变化

问题主要在于步骤4和步骤5(也是第3步和第4步,但这实际上并不明显)。

示例

作为用户,我可以清楚地看到正在生成的表行,但表格单元格仍为空。几十毫秒后,会显示值。我不确定这是否是默认的Angular行为,或者我的浏览器是否有足够的麻烦来快速呈现对HTML的更改。

我的想法

我猜这个问题与浏览器更新视口的方式交织在一起。我还没有真正深入研究,但在我看来,Angular实际上已应用了这些更改,但它们尚未被浏览器呈现。使用指向$ last标志的主数据表的指令,我可以检测到ng-repeat完成和视图呈现之间的相当大的延迟。这可能是因为浏览器的细节太多了,但也许其他人对此有一些想法要分享:)

2 个答案:

答案 0 :(得分:2)

你可以拥有最低优先级的指令......例如-1并使用该指令显示或隐藏spinner / gif元素

作为具有最低优先级的指令,这将在视图更新中最后执行。所以show-spinner在这个指令的一部分可能是假的,因此只有在渲染所有更改后,spinner才会隐藏...

PLUNKER LINK

答案 1 :(得分:2)

这可能有点hackish,但我有一种情况,外部lib必须将事件监听器附加到ngRepeat生成的元素。显然,当模型观察者解雇时,元素还没有出现,所以我所做的是ngRepeat元素上的自定义指令,它将监视ngRepeat的{​​{1}}属性然后$last 1}}需要回调。这是个主意:

$evalAsync

考虑到这一点,您可以隐藏加载程序图像,而不是在释放锁定时,但是当某个事件(比如.directive('onRepeatFinish', function() { return { restrict: 'A', link: function(scope, element, attributes) { if (scope.$last === true) { scope.$evalAsync(attributes.onRepeatFinish); } } }; }) )由此指令发送时。

模板:

renderComplete
$ rootScope中的

处理程序:

<div ng-repeat="record in data" on-repeat-finish="$emit('renderComplete')"></div>