本文介绍了为什么我会在包装$ AngularJS超时服务功能没有延迟,就像他们在NG-文件上传的例子使用code呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在大多数样品含有使用code为NG-文件上传的小提琴的()就像一个在(),上传回复回调函数的包裹code在 $超时服务电话的,但这些电话中没有通过的任何延迟参数

In most of the fiddles containing sample usage code for ng-file-upload (https://github.com/danialfarid/ng-file-upload) like the one at (http://jsfiddle.net/danialfarid/maqbzv15/1118/), the upload response callback functions wrap their code in a $timeout service call, but these calls do not have any delay parameter passed in.

该Angular.js文档为 $超时( $超时)表示,延迟是可选的,但你为什么要做出 $通话超时,如果不耽误code正在运行。换句话说,而不是下面,为什么不这样做一前一后:

The Angular.js docs for $timeout (https://docs.angularjs.org/api/ng/service/$timeout) indicate that the delay is optional, but why would you want to make a call to $timeout if not to delay the code being run. In other words instead of the following, why not do the one after:

//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));
});
}
}]);

有什么理由 $超时包装在所有这些例子呢?将在该位置以下file.upload呼叫工作:

Is there any reason for the $timeout wrapper in all these examples? Would the following file.upload call work in its place?:

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));
});

编辑:我可以看到,它似乎没有 $超时包装运行,但它包含在所有的例子其实让我觉得这是故意的,这可能意味着有一个安全/健壮性/浏览器的兼容性优势的情况下,我不明白这里。

I can see that it appears to run without the $timeout wrapper, but the fact it's included in all the examples makes me think it's deliberate, which probably means there's a security/robustness/browser compatibility edge case I don't understand here.

推荐答案

这是所有做与角的消化周期。我会尽力我继续解释摘要周期是与前一个例子来证明这一点。想象一下以下code:

It's all to do with Angular's digest cycle. I'll try to demonstrate this with an example before I go on to explain what the digest cycle is. Imagine the following code:

angular.module('app', []).controller('TestController', ['$scope', function($scope){
    $scope.name = 'Tom';
    setTimeout(function(){
        $scope.name = 'Bob';
    }, 2000);
}]);

有与此code的固有问题。正如我们改变 $ scope.name 的变量2秒后,角完全不知道这种变化 $ scope.name 。如果你现在考虑下面的例子中,我们使用 $超时而不是:

There's an inherent problem with this code. As much as we change the variable of $scope.name after 2 seconds, Angular is completely unaware of this change to $scope.name. If you now consider the following example where we use $timeout instead:

angular.module('app', []).controller('TestController', ['$scope', '$timeout', function($scope, $timeout){
    $scope.name = 'Tom';
    $timeout(function(){
        $scope.name = 'Bob';
    }, 2000);
}]);

角将调用匿名函数两秒钟之后,然而,它随后将开始角度的消化周期。这是 $超时和setTimeout的,消化周期正在运行。

Angular will call the anonymous function after two seconds, however, it will then start off Angular's digest cycle. This is the main difference between $timeout and setTimeout, the digest cycle being run.

摘要周期(简单地说)角去了所有的观察者(绑定)的,检查任何更改并重新渲染的地方不合适。你可能已经看到了提至 $ $范围适用其他地方 - 。这是怎么开始的消化周期

The digest cycle is (put simply) Angular going over all of the watchers (bindings), checking for any changes and re-rendering where appropiate. You may have seen a mention to $scope.$apply elsewhere - this is how to start the digest cycle.

至于您所提供的例子:如果没有使用 $超时,角也不会知道,任何已经作了修改,因此,您的视图不会更新。我提到 $范围。$适用较早所以你可能会奇怪,为什么我们不只是用这个来代替?使用$范围的问题。$应用是,你不能确保摘要周期是不是已经在进行中。如果你调用它,而一个occcuring,你会看到一个错误 $消化正在进行中。 $超时只会在当前周期之后运行,因此,不会发生这个错误。

With regards to the example you provided: If the $timeout wasn't used, Angular wouldn't be aware that any changes have been made and as such, your view wouldn't update. I mentioned $scope.$apply earlier so you may be wondering why we don't just use this instead? The problem with using $scope.$apply is that you cannot be sure that a digest cycle isn't in progress already. If you do call it while one is occcuring, you'll see an error "$digest is already in progress". $timeout will only run after the current cycle and as such, this error won't happen.

人们通常使用 $超时没有任何延迟通知角的变化已经由第三方做出(像你的文件上传),这否则不会知道发生了什么。

People often use $timeout without any delay to notify Angular that a change has been made by a third party (like your file uploader), that it otherwise wouldn't know had happened.

希望这将清除的东西了。

Hopefully this clears things up.

汤姆

这篇关于为什么我会在包装$ AngularJS超时服务功能没有延迟,就像他们在NG-文件上传的例子使用code呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 19:03