$timeout(https://docs.angularjs.org/api/ng/service/ $timeout)的Angular.js文档表明延迟是可选的,但是如果不延迟正在运行的代码,为什么要调用$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; },parseInt(100.0 * evt.loaded / evt.total)); });
编辑:我可以看到它似乎没有$timeout包装器运行,但它包含在所有示例中的事实使我认为这是故意的,这可能意味着有一个安全性/健壮性/浏览器兼容性边缘情况我不明白这里.
angular.module('app',[]).controller('TestController',function($scope){ $scope.name = 'Tom'; setTimeout(function(){ $scope.name = 'Bob'; },2000); }]);
这段代码存在固有的问题.尽管我们在2秒后更改了$scope.name的变量,但Angular完全没有意识到对$scope.name的这一更改.如果您现在考虑以下我们使用$timeout的示例:
angular.module('app',function($scope,$timeout){ $scope.name = 'Tom'; $timeout(function(){ $scope.name = 'Bob'; },2000); }]);
Angular将在两秒后调用匿名函数,然后,它将从Angular的摘要周期开始.这是$timeout和setTimeout之间的主要区别,即正在运行的摘要周期.
摘要周期(简单地说)Angular遍历所有观察者(绑定),检查任何更改并重新呈现适当的位置.您可能已经看到提到$scope.$适用于其他地方 – 这是如何开始摘要周期.
关于您提供的示例:如果未使用$timeout,Angular将不会意识到已进行任何更改,因此您的视图将不会更新.我之前提到$scope.$申请,所以你可能想知道为什么我们不只是使用它?使用$scope.$apply的问题是您无法确定摘要周期是否已在进行中.如果你在一个人发现时调用它,你会看到一个错误“$digest已在进行中”. $timeout只会在当前周期之后运行,因此不会发生此错误.
人们通常会毫不拖延地使用$timeout来通知Angular第三方(比如你的文件上传者)已做出更改,否则就不会知道发生了什么.
希望这可以解决问题.
汤姆