在大多数小提琴中包含ng-file-upload(https://github.com/danialfarid/ng-file- upload)的示例用法代码,例如(http://jsfiddle.net/danialfarid/maqbzv15/1118) /),上传响应回调函数会将其代码包装在$timeout服务调用中,但是这些调用没有传入任何延迟参数。
$timeout
$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; }, 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包装程序就可以运行,但是所有示例中都包含了它,这使我认为它是有意的,这可能意味着存在安全性/健壮性/浏览器兼容性方面的问题,我在这里不了解。
这与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代替我们使用:
$scope.name
angular.module('app', []).controller('TestController', ['$scope', '$timeout', function($scope, $timeout){ $scope.name = 'Tom'; $timeout(function(){ $scope.name = 'Bob'; }, 2000); }]);
Angular将在两秒钟后调用匿名函数,但是,它将从Angular的摘要周期开始。这是$timeout和之间的主要区别setTimeout,正在运行摘要循环。
setTimeout
摘要周期是(简单地)将Angular遍历所有观察者(绑定),检查是否有任何更改并在适当的地方重新呈现。您可能已经在$scope.$apply其他地方看到过提及- 这是开始摘要循环的方法。
$scope.$apply
关于您提供的示例:如果$timeout未使用,Angular不会知道已进行任何更改,因此,您的视图将不会更新。我$scope.$apply之前提到过,所以您可能想知道为什么我们不只是使用它呢?使用的问题$scope.$apply是您不能确定摘要循环尚未进行。如果您确实在通话时调用它,则会看到错误“ $digest is already in progress”。$timeout仅在当前周期之后运行,因此不会发生此错误。
$digest is already in progress
人们经常毫不犹豫地使用$timeoutAngular通知第三方(例如您的文件上传器)已进行了更改,否则该更改将不会发生。
希望这可以清除一切。
汤姆