在大多数包含 ng-file-upload ( https://github.com/danialfarid/ng-file-upload ) 示例使用代码的 fiddle 中,例如 ( http://jsfiddle.net/danialfarid/maqbzv15/1118/ ),上传响应回调函数将其代码包装在 $timeout
中。服务调用,但这些调用没有传入任何延迟参数。$timeout
的 Angular.js 文档( https://docs.angularjs.org/api/ng/service/ $timeout) 表示延迟是可选的,但为什么要调用 $timeout
如果不是为了延迟正在运行的代码。换句话说,为什么不做下面的,而不是下面的:
//inject angular file upload directives and services.
var app = angular.module('fileUpload', ['ngFileUpload']);
app.controller('MyCtrl', ['$scope', 'Upload', '$timeout', function ($scope, Upload, $timeout) {
$scope.uploadPic = function(file) {
file.upload = Upload.upload({
url: 'https://angular-file-upload-cors-srv.appspot.com/upload',
data: {username: $scope.username, file: file},
});
file.upload.then(function (response) {
$timeout(function () {
file.result = response.data;
});
}, function (response) {
if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
}, function (evt) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
}
}]);
$timeout
有什么原因吗?所有这些例子中的包装器?以下 file.upload 调用会代替它工作吗?:file.upload.then(function (response) {
file.result = response.data;
}, function (response) {
if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
}, function (evt) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
编辑:我可以看到它似乎在没有
$timeout
的情况下运行wrapper,但它包含在所有示例中的事实让我认为这是故意的,这可能意味着存在我在这里不理解的安全/健壮性/浏览器兼容性边缘情况。
最佳答案
这一切都与 Angular 的摘要循环有关。在继续解释什么是摘要循环之前,我将尝试通过一个示例来证明这一点。想象一下下面的代码:
angular.module('app', []).controller('TestController', ['$scope', function($scope){
$scope.name = 'Tom';
setTimeout(function(){
$scope.name = 'Bob';
}, 2000);
}]);
这段代码有一个固有的问题。就像我们改变
$scope.name
的变量一样2 秒后,Angular 完全不知道对 $scope.name
的更改。 .如果您现在考虑以下示例,我们使用 $timeout
反而:angular.module('app', []).controller('TestController', ['$scope', '$timeout', function($scope, $timeout){
$scope.name = 'Tom';
$timeout(function(){
$scope.name = 'Bob';
}, 2000);
}]);
Angular 将在两秒后调用匿名函数,然而,它将开始 Angular 的摘要循环。这是
$timeout
之间的主要区别。和 setTimeout
,正在运行的摘要循环。摘要循环是(简单地说)Angular遍历所有观察者(绑定(bind)),检查任何更改并在适当的地方重新渲染。您可能已经看到对
$scope.$apply
的提及其他地方 - 这是如何开始消化周期。关于您提供的示例:如果
$timeout
没有使用,Angular 不会意识到已经进行了任何更改,因此您的 View 不会更新。我提到了$scope.$apply
早些时候,所以您可能想知道为什么我们不直接使用它?使用 $scope.$apply
的问题是您无法确定摘要周期尚未进行。如果你在一个发生时调用它,你会看到一个错误“$digest is already in progress
”。 $timeout
只会在当前周期之后运行,因此不会发生此错误。人们经常使用
$timeout
毫不拖延地通知 Angular 第三方(例如您的文件上传者)已进行了更改,否则它不会知道发生了更改。希望这可以解决问题。
汤姆
关于angularjs - 为什么我会像在 ng-file-upload 示例使用代码中那样在 AngularJS $timeout 服务中包装一个函数,而不会延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36108158/