Hor*_*ren 31 javascript angularjs
在angularjs 1.2中,像过滤ng-repeat多行(> 2,000行)的操作可能变得非常慢(> 1秒).
我知道我可以使用limitTo分页,自定义过滤器等来优化执行时间,但我仍然有兴趣知道在浏览器忙于运行长脚本时是否可以显示加载动画.
在角度的情况下,我认为可以在$digest运行时调用,因为这似乎是占用大部分时间的主要功能,并且可能被多次调用.
在一个相关的问题中,没有给出有用的答案.任何帮助非常感谢!
Nik*_*los 20
问题是只要Javascript正在执行,UI就没有机会更新.即使您在过滤之前呈现微调器,只要Angular忙,它就会显示为"冻结".
克服这种情况的一种方法是过滤块,如果有更多数据可用,则在小块后再次过滤$timeout.超时使UI线程有机会运行并显示更改和动画.
这里展示了这个原则的小提琴.
它不使用Angular的过滤器(它们是同步的).相反,它data使用以下函数过滤数组:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它需要2个支持变量:$scope.filtering是true当过滤器处于活动状态,给我们以显示微调和禁止输入的机会; $scope.filteredData接收过滤器的结果.
有3个隐藏参数:
counter < 5)的目的很小,以证明效果$timeout(innerFilter, 10))应该很小,但足以给UI线程一些时间来响应这只是概念的证明; 我建议重构它(可能是指令)以供实际使用.
以下是步骤:
ng-view的
fixed定位之外.<div class="activity-box" ng-show="!!message">
<img src="img/load.png" width="40" height="40" />
<span>{{ message }}</span>
</div>
Run Code Online (Sandbox Code Playgroud)
activity 指示:具有单个属性的简单指令message.请注意ng-show上面模板中的指令.在message既用来切换活动的指标,并设置用户的信息文本.
app.directive('activity', [
function () {
return {
restrict: 'EA',
templateUrl: '/templates/activity.html',
replace: true,
scope: {
message: '@'
},
link: function (scope, element, attrs) {}
};
}
]);
Run Code Online (Sandbox Code Playgroud)
<body ng-controller="appController">
<div ng-view id="content-view">...</div>
<div activity message="{{ activityMessage }}"></div>
</body>
Run Code Online (Sandbox Code Playgroud)
注意,activity指令放在外面ng-view.它将在您的单页面应用的每个部分提供.
app.controller('appController',
function ($scope, $timeout) {
// You would better place these two methods below, inside a
// service or factory; so you can inject that service anywhere
// within the app and toggle the activity indicator on/off where needed
$scope.showActivity = function (msg) {
$timeout(function () {
$scope.activityMessage = msg;
});
};
$scope.hideActivity = function () {
$timeout(function () {
$scope.activityMessage = '';
}, 1000); // message will be visible at least 1 sec
};
// So here is how we do it:
// "Before" the process, we set the message and the activity indicator is shown
$scope.showActivity('Loading items...');
var i;
for (i = 0; i < 10000; i += 1) {
// here goes some heavy process
}
// "After" the process completes, we hide the activity indicator.
$scope.hideActivity();
});
Run Code Online (Sandbox Code Playgroud)
当然,你也可以在其他地方使用它.例如,你可以$scope.hideActivity();在承诺解决时打电话.或切换上的活动request及response的httpInterceptor是一个好主意了.
.activity-box {
display: block;
position: fixed; /* fixed position so it doesn't scroll */
z-index: 9999; /* on top of everything else */
width: 250px;
margin-left: -125px; /* horizontally centered */
left: 50%;
top: 10px; /* displayed on the top of the page, just like Gmail's yellow info-box */
height: 40px;
padding: 10px;
background-color: #f3e9b5;
border-radius: 4px;
}
/* styles for the activity text */
.activity-box span {
display: block;
position: relative;
margin-left: 60px;
margin-top: 10px;
font-family: arial;
font-size: 15px;
}
/* animating a static image */
.activity-box img {
display: block;
position: absolute;
width: 40px;
height: 40px;
/* Below is the key for the rotating animation */
-webkit-animation: spin 1s infinite linear;
-moz-animation: spin 1s infinite linear;
-o-animation: spin 1s infinite linear;
animation: spin 1s infinite linear;
}
/* keyframe animation defined for various browsers */
@-moz-keyframes spin {
0% { -moz-transform: rotate(0deg); }
100% { -moz-transform: rotate(359deg); }
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(359deg); }
}
@-o-keyframes spin {
0% { -o-transform: rotate(0deg); }
100% { -o-transform: rotate(359deg); }
}
@-ms-keyframes spin {
0% { -ms-transform: rotate(0deg); }
100% { -ms-transform: rotate(359deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(359deg); }
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
35567 次 |
| 最近记录: |