使用AngularJS显示慢速脚本的加载动画? [英] Show loading animation for slow script using AngularJS?
问题描述
在angularjs 1.2操作中,例如过滤带有多行(> 2,000行)的 ng-repeat
可能会变得非常慢(> 1秒)。
我知道我可以使用 limitTo
,分页,自定义过滤器等优化执行时间,但我仍然有兴趣知道是否可以在浏览器中显示加载动画正忙于运行长脚本。
In angularjs 1.2 operations like filtering an ng-repeat
with many rows (>2,000 rows) can become quite slow (>1 sec).
I know I can optimize execution times using limitTo
, pagination, custom filters, etc. but I'm still interested to know if it's possible to show a loading animation while the browser is busy running long scripts.
如果是角度我认为只要 $ digest
正在运行就可以调用这似乎是占用大部分时间的主要功能,可能会多次调用。
In case of angular I think that could be invoked whenever $digest
is running because that seems to be the main function that takes up most time and might be called several times.
在相关内容中问题没有给出有用的答案。任何帮助都非常感谢!
In a related question there were no useful answers given. Any help greatly appreciated!
推荐答案
问题是只要Javascript正在执行,UI就没有机会更新。即使您在过滤之前呈现微调器,只要Angular忙,它就会显示为冻结。
The problem is that as long as Javascript is executing, the UI gets no chance to update. Even if you present a spinner before filtering, it will appear "frozen" as long as Angular is busy.
克服此问题的一种方法是以块为单位进行过滤,如果有更多数据可用,请在小 $ timeout
之后再次过滤。超时使UI线程有机会运行并显示更改和动画。
A way to overcome this is to filter in chunks and, if more data are available, filter again after a small $timeout
. The timeout gives the UI thread a chance to run and display changes and animations.
演示原理的小提琴是这里。
它不使用Angular的过滤器(它们是同步的)。相反,它使用以下函数过滤数据
数组:
It does not use Angular's filters (they are synchronous). Instead it filters the data
array with the following function:
function filter() {
var i=0, filtered = [];
innerFilter();
function innerFilter() {
var counter;
for( counter=0; i < $scope.data.length && counter < 5; counter++, i++ ) {
/////////////////////////////////////////////////////////
// REAL FILTER LOGIC; BETTER SPLIT TO ANOTHER FUNCTION //
if( $scope.data[i].indexOf($scope.filter) >= 0 ) {
filtered.push($scope.data[i]);
}
/////////////////////////////////////////////////////////
}
if( i === $scope.data.length ) {
$scope.filteredData = filtered;
$scope.filtering = false;
}
else {
$timeout(innerFilter, 10);
}
}
}
它需要2个支持变量:过滤器处于活动状态时, $ scope.filtering
为 true
,让我们有机会显示微调器并禁用输入; $ scope.filteredData
收到过滤器的结果。
It requires 2 support variables: $scope.filtering
is true
when the filter is active, giving us the chance to display the spinner and disable the input; $scope.filteredData
receives the result of the filter.
有3个隐藏参数:
- 块大小(
计数器< 5
)的目的很小,以证明效果 - 超时延迟(
$ timeout(innerFilter,10)
)应该很小,但足以让UI线程有时间做出响应 - 实际的过滤器逻辑,它应该是现实生活场景中的回调。
- the chunk size (
counter < 5
) is small on purpose to demonstrate the effect - the timeout delay (
$timeout(innerFilter, 10)
) should be small, but enough to give the UI thread some time to be responsive - the actual filter logic, which should probably be a callback in real life scenarios.
这只是一个概念证明;我建议重构它(可能是指令)以供实际使用。
This is only a proof of concept; I would suggest refactoring it (to a directive probably) for real use.
这篇关于使用AngularJS显示慢速脚本的加载动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!