enc*_*est 5 timeout angularjs ng-file-upload
在大多数样品含有使用码为NG-文件上传的小提琴(的https://github.com/danialfarid/ng-file-upload)之类的一个在(http://jsfiddle.net/danialfarid/maqbzv15/1118 /),上传响应回调函数将其代码包装在$timeout服务调用中,但这些调用没有传入任何延迟参数.
$timeout(https://docs.angularjs.org/api/ng/service/ $ timeout)的Angular.js文档表明延迟是可选的,但是为什么要调用$timeoutif if not not delay code is 跑.换句话说,而不是以下,为什么不在之后做一个:
//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));
});
}
}]);
Run Code Online (Sandbox Code Playgroud)
$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));
});
Run Code Online (Sandbox Code Playgroud)
编辑:我可以看到,它似乎没有运行$timeout的包装,但它包含在所有的例子其实让我觉得这是故意的,这可能意味着有一个安全/健壮性/浏览器的兼容性优势的情况下,我不明白这里.
mad*_*kst 11
这与Angular的消化周期有关.在我继续解释摘要周期是什么之前,我将尝试用一个例子来证明这一点.想象一下以下代码:
angular.module('app', []).controller('TestController', ['$scope', function($scope){
$scope.name = 'Tom';
setTimeout(function(){
$scope.name = 'Bob';
}, 2000);
}]);
Run Code Online (Sandbox Code Playgroud)
这段代码存在固有的问题.尽管我们$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);
}]);
Run Code Online (Sandbox Code Playgroud)
Angular将在两秒后调用匿名函数,然后,它将从Angular的摘要周期开始.这是$timeout和setTimeout正在运行的摘要周期之间的主要区别.
摘要周期(简单地说)Angular遍历所有观察者(绑定),检查任何更改并重新呈现适当的位置.您可能已经看到$scope.$apply其他地方的提及- 这是如何开始摘要周期.
关于您提供的示例:如果$timeout未使用,Angular将不会意识到已进行任何更改,因此您的视图将不会更新.我$scope.$apply之前提到过,所以你可能想知道我们为什么不用这个呢?使用的问题$scope.$apply是您无法确定摘要周期是否已在进行中.如果你在一个人发现时调用它,你会看到一个错误" $digest is already in progress".$timeout只会在当前周期之后运行,因此不会发生此错误.
人们经常$timeout毫不迟疑地通知Angular第三方(比如你的文件上传者)已经做出了改变,否则就不会知道发生了什么.
希望这可以解决问题.
汤姆