我试图提供使用angularjs运行的任务的进度,但在执行deferred.notify()时更新绑定时遇到问题。
以下是我为重现问题(Plunker)而做的一个例子
var app = angular.module('app', [
'ngAnimate',
'ui.bootstrap'
]);
(function() {
'use strict';
var controllerId = 'testController';
angular.module('app').controller(controllerId, ['$timeout', '$q', '$scope', testController]);
function testController($timeout, $q, $scope) {
$scope.callLongProcess = callLongProcess;
$scope.value = '-';
$scope.progress = 0;
function longProccess() {
var def = $q.defer();
$timeout(function() {
for (var i = 0; i < 200000; i++) {
if (i % 2 === 0) {
//WHY THIS LINES DOES NOT UPDATE THE UI WHEN RUNNING
def.notify(i);
$scope.$apply();
}
}
def.resolve("success");
}, 0);
return def.promise;
}
function callLongProcess() {
longProccess()
.then(
function(results) {
$scope.value = results;
},
function(error) {
$scope.value = error;
},
function(progress) {
$scope.progress = progress;
})
}
}
})();
您在超时函数中陷入了200000次迭代的紧密循环。尽管您已经调用了$scope$应用100000次,循环必须在angular有机会做任何事情之前完成。这是因为$scope$application通过向主浏览器事件循环添加另一个事件异步运行,而不是立即运行。
如果你想更新进度,你必须将"longProcess"函数分解成更小的块,你可以通过回调异步处理这些块。