web-dev-qa-db-fra.com

Charge de FileReader avec résultat et paramètre

Je n'arrive pas à obtenir à la fois le résultat du filereader et certains paramètres dans une fonction onload. Voici mon code:

HTML du contrôle:

<input type="file" id="files_input" multiple/>

Fonction Javascript:

function openFiles(evt){
    var files = evt.target.files;
    for (var i = 0; i < files.length; i++) {
      var file=files[i];
      reader = new FileReader();
      reader.onload = function(){
          var data = $.csv.toArrays(this.result,{separator:'\t'});
      };
      reader.readAsText(file);
    }
  }

Ajouter un évènement:

 files_input.addEventListener("change", openFiles, false);

Je utilise le filereader.result, dans la fonction onload. Si j'utilise un paramètre, comme fichier, pour cette fonction, je ne pourrai plus accéder au résultat. Par exemple, j'aimerais utiliser file.name dans la fonction onload. Comment résoudre ce problème ?

20
PatriceG

Essayez d'encapsuler votre fonction onload dans une autre fonction. Ici, la fermeture vous donne accès à chaque fichier en cours de traitement via la variable f:

function openFiles(evt){
    var files = evt.target.files;

    for (var i = 0, len = files.length; i < len; i++) {
        var file = files[i];

        var reader = new FileReader();

        reader.onload = (function(f) {
            return function(e) {
                // Here you can use `e.target.result` or `this.result`
                // and `f.name`.
            };
        })(file);

        reader.readAsText(file);
    }
}

Pour une discussion sur les raisons pour lesquelles une fermeture est requise ici, voir ces questions connexes:

43
Chris

Vous devez utiliser la fermeture au gestionnaire "onload". Exemple: http://jsfiddle.net/2bjt7Lon/

reader.onload = (function (file) { // here we save variable 'file' in closure
     return function (e) { // return handler function for 'onload' event
         var data = this.result; // do some thing with data
     }
})(file);
6
sergolius

La gestion des événements est asynchrone et récupère donc la dernière valeur de toutes les variables locales incluses (c'est-à-dire la fermeture). Pour lier une variable locale particulière à l'événement, vous devez suivre le code suggéré par les utilisateurs ci-dessus ou vous pouvez regarder cet exemple de travail: -

http://jsfiddle.net/sahilbatla/hjk3u2ee/

function openFiles(evt){
  var files = evt.target.files;
  for (var i = 0; i < files.length; i++) {
    var file=files[i];
    reader = new FileReader();
    reader.onload = (function(file){
      return function() {
        console.log(file)
      }
    })(file);
    reader.readAsText(file);
  }
}

#Using jQuery document ready
$(function() {
  files_input.addEventListener("change", openFiles, false);
});
3
sahilbathla

Pour TypeScript;

for (var i = 0; i < files.length; i++) {
  var file = files[i];

  var reader = new FileReader();

  reader.onload = ((file: any) => {
    return (e: Event) => {
      //use "e" or "file"
    }
  })(file);

  reader.readAsText(file);
}
0