Téléchargement de fichiers à l'aide d'AngularJS

296

Voici mon formulaire HTML:

<form name="myForm" ng-submit="">
    <input ng-model='file' type="file"/>
    <input type="submit" value='Submit'/>
</form>

Je souhaite télécharger une image de la machine locale et je souhaite lire le contenu du fichier téléchargé. Tout cela, je veux le faire en utilisant AngularJS.

Lorsque j'essaie d'imprimer la valeur de $scope.filecelle - ci est indéfinie.

Aditya Sethi
la source

Réponses:

344

Certaines des réponses FormData()proposées ici sont proposées, mais malheureusement, il s'agit d'un objet navigateur non disponible dans Internet Explorer 9 et versions antérieures. Si vous devez prendre en charge ces anciens navigateurs, vous aurez besoin d'une stratégie de sauvegarde telle que l'utilisation de <iframe>Flash ou.

Il existe déjà de nombreux modules Angular.js pour effectuer le téléchargement de fichiers. Ces deux ont un support explicite pour les anciens navigateurs:

Et quelques autres options:

L'une d'elles devrait correspondre à votre projet ou vous donner un aperçu de la façon de la coder vous-même.

Anoyz
la source
4
Une autre solution (IaaS pour le téléchargement de fichiers): github.com/uploadcare/angular-uploadcare
David Avsajanishvili
27
EggHead a une bonne vidéo à ce sujet - egghead.io/lessons/angularjs-file-uploads
Adam Zerner
2
danialfarid / angular-file-upload est renommé ng-file-upload
Michael
5
Réponse de 3 ans. IE 9 est DEAD maintenant en 2016.
user2404597
5
Je pense que vous devriez mettre à jour votre réponse pour avoir une bonne solution au lieu de pointer vers des liens. C'est la façon de déborder la pile. Sinon, faites cela comme un commentaire.
Alex Reynolds
178

Le plus simple est d'utiliser l'API HTML5, à savoir FileReader

Le HTML est assez simple:

<input type="file" id="file" name="file"/>
<button ng-click="add()">Add</button>

Dans votre contrôleur, définissez la méthode «ajouter»:

$scope.add = function() {
    var f = document.getElementById('file').files[0],
        r = new FileReader();

    r.onloadend = function(e) {
      var data = e.target.result;
      //send your binary data via $http or $resource or do anything else with it
    }

    r.readAsBinaryString(f);
}

Compatibilité du navigateur

Navigateurs de bureau

Edge 12, Firefox (Gecko) 3.6 (1.9.2), Chrome 7, Opera * 12.02, Safari 6.0.2

Navigateurs mobiles

Firefox (Gecko) 32, Chrome 3, Opera * 11.5, Safari 6.1

Remarque: la méthode readAsBinaryString () est déconseillée et readAsArrayBuffer () doit être utilisée à la place.

yagger
la source
10
FileReader est une classe de l'API de fichier HTML5 standard w3.org/TR/FileAPI . Il vous permet de lire les données du fichier spécifié dans l'élément d'entrée html et de les traiter dans la onloadendfonction de rappel. Vous n'avez besoin d'aucune bibliothèque pour utiliser cette API, elle est déjà dans votre navigateur (sauf si vous en utilisez une très ancienne). J'espère que cela t'aides.
yagger
15
FileReader.readAsBinaryString est obsolète depuis le projet de travail du 12 juillet 2012 du W3C.
Shane Stillwell
13
Vous ne devriez pas accéder au DOM avec angular. C'est une très mauvaise pratique.
jeanmatthieud
9
@Siderex, pas dans le contrôleur, mais c'est vraiment génial de le faire à partir de la directive. En fait, c'est à cela que servent les directives. Vous pouvez en lire plus dans Angular docs docs.angularjs.org/guide/directive
yagger
1
@yagger existe-t-il une raison particulière pour laquelle vos liens font référence à la readAsArrayBufferméthode FileReaderSync (qui n'est disponible que dans les travailleurs Web) au lieu de l' API FileReader asynchrone habituelle ?
doldt
58

Il s'agit du navigateur moderne, sans bibliothèques tierces. Fonctionne sur tous les derniers navigateurs.

 app.directive('myDirective', function (httpPostFactory) {
    return {
        restrict: 'A',
        scope: true,
        link: function (scope, element, attr) {

            element.bind('change', function () {
                var formData = new FormData();
                formData.append('file', element[0].files[0]);
                httpPostFactory('upload_image.php', formData, function (callback) {
                   // recieve image name to use in a ng-src 
                    console.log(callback);
                });
            });

        }
    };
});

app.factory('httpPostFactory', function ($http) {
    return function (file, data, callback) {
        $http({
            url: file,
            method: "POST",
            data: data,
            headers: {'Content-Type': undefined}
        }).success(function (response) {
            callback(response);
        });
    };
});

HTML:

<input data-my-Directive type="file" name="file">

PHP:

if (isset($_FILES['file']) && $_FILES['file']['error'] == 0) {

// uploads image in the folder images
    $temp = explode(".", $_FILES["file"]["name"]);
    $newfilename = substr(md5(time()), 0, 10) . '.' . end($temp);
    move_uploaded_file($_FILES['file']['tmp_name'], 'images/' . $newfilename);

// give callback to your angular code with the image src name
    echo json_encode($newfilename);
}

js fiddle (seulement front-end) https://jsfiddle.net/vince123/8d18tsey/31/

Vince Verhoeven
la source
Comment voulez-vous récupérer le fichier dans le nœud?
Juicy
Plus de détails? Avez-vous besoin d'une ng-submitou d'une action de formulaire? Cela en soi ne fait rien
Aron
@Emaborsa bonjour J'ai ajouté un jsfiddle et fait un exemple de code php plus complet. Il soumet l'image après que la valeur de l'entrée de fichier a changé, donc aucun ng-submit requis.
Vince Verhoeven
La solution la plus simple parfaite, mais il m'a fallu beaucoup de temps pour trouver comment obtenir mes services WCF pour faire face aux données qui étaient téléchargées. Il est essentiel que vous preniez le flux de données et le passiez par quelque chose comme MultiParser pour lire réellement les données du fichier: stackoverflow.com/a/23702692/391605 Sinon, vous stockerez des octets bruts de "------ WebKitFormBoundary Contenu-Disposition: ... etc .. "
Mike Gledhill
J'avais besoin d'ajouter la propriété 'transformRequest: angular.identity' à l'objet de requête $ http comme indiqué par Manoy Ojha un peu plus bas sinon le Content-Type ne serait pas défini correctement et l'exemple ne fonctionnerait pas.
Gregor Slavec
38

Voici un exemple pratique de téléchargement de fichiers:

http://jsfiddle.net/vishalvasani/4hqVu/

Dans cette seule fonction appelée

setFiles

Depuis la vue qui mettra à jour le tableau de fichiers dans le contrôleur

ou

Vous pouvez vérifier le téléchargement de fichiers jQuery en utilisant AngularJS

http://blueimp.github.io/jQuery-File-Upload/angularjs.html

JQuery Guru
la source
Salut, je cherchais quelque chose à travers lequel je peux simplement télécharger un fichier et afficher juste en dessous. Cependant, dans votre exemple, je n'ai pas pu faire de même. Ne me dérange pas, mais je suis nouveau dans cette angularjs et mon intention d'apprendre à faire cet objectif particulier d'une manière plus simple mais robuste.
Aditya Sethi
Cela a beaucoup aidé. Merci!
RachelD
Excellent exemple sans utiliser de bibliothèque / extension supplémentaire. Merci.
markdsievers
4
Très utile, juste une note .. cela utilise l'API de fichier qui ne fonctionne pas dans IE9 ou ci-dessous.
ArjaaAine
Une idée comment j'obtiens des erreurs du résultat? Le serveur peut générer une erreur et je voudrais afficher ce message d'erreur ...
CularBytes
17

Vous pouvez obtenir le fichier et le dossier agréable téléchargement à l' aide flow.js .

https://github.com/flowjs/ng-flow

Découvrez une démo ici

http://flowjs.github.io/ng-flow/

Il ne prend pas en charge IE7, IE8, IE9, vous devrez donc éventuellement utiliser une couche de compatibilité

https://github.com/flowjs/fusty-flow.js

Fizer Khan
la source
`flow.js 'est fantastique, mais manque encore de documentation. J'ai besoin de manipuler un seul téléchargement et d'ajouter un aperçu et également d'envoyer un bouton d'événement séparé, mais je ne sais pas comment le faire.
Francis Rodrigues
14

Utilisez l' onchangeévénement pour passer l'élément de fichier d'entrée à votre fonction.

<input type="file" onchange="angular.element(this).scope().fileSelected(this)" />

Ainsi, lorsqu'un utilisateur sélectionne un fichier, vous y avez une référence sans que l'utilisateur ait besoin de cliquer sur un bouton "Ajouter" ou "Télécharger".

$scope.fileSelected = function (element) {
    var myFileSelected = element.files[0];
};
James Lawruk
la source
2
Cela ne fonctionne pas comme souhaité. Voici mon flux de travail: 1. Actualisez la page 2. Ajoutez un nouveau fichier. ** Le premier fichier ajouté n'est toujours pas défini. ** 3. Ajoutez un autre fichier. Désormais, chaque fichier téléchargé est le fichier précédent que j'ai ajouté. Donc, pour le 2ème fichier que j'ajoute, cela téléchargerait le premier fichier que j'ai ajouté (qui a en fait échoué)
Pulkit Pahwa
1
la meilleure méthode!
Stepan Yakovenko
11

J'ai essayé toutes les alternatives que donne @Anoyz (réponse correcte) ... et la meilleure solution est https://github.com/danialfarid/angular-file-upload

Certaines fonctionnalités:

  • Le progrès
  • Multifichiers
  • Des champs
  • Anciens navigateurs (IE8-9)

Ça marche bien pour moi. Il suffit de faire attention aux instructions.

Côté serveur, j'utilise des middleware NodeJs, Express 4 et Multer pour gérer les requêtes en plusieurs parties.

Javier Cornejo Alfaro
la source
Comment montrez-vous les images? Depuis le backend, ils entrent avec succès, mais ils sont enregistrés sous nlzt9LJWRrAZEO3ZteZUOgGcle format .png mais sans. Comment ajouter ça?
Saras Arya
9

HTML

<html>
    <head></head>

<body ng-app = "myApp">

  <form ng-controller = "myCtrl">
     <input type = "file" file-model="files" multiple/>
     <button ng-click = "uploadFile()">upload me</button>
     <li ng-repeat="file in files">{{file.name}}</li>
  </form>

Scripts

  <script src = 
     "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
  <script>
    angular.module('myApp', []).directive('fileModel', ['$parse', function ($parse) {
        return {
           restrict: 'A',
           link: function(scope, element, attrs) {
              element.bind('change', function(){
              $parse(attrs.fileModel).assign(scope,element[0].files)
                 scope.$apply();
              });
           }
        };
     }]).controller('myCtrl', ['$scope', '$http', function($scope, $http){


       $scope.uploadFile=function(){
       var fd=new FormData();
        console.log($scope.files);
        angular.forEach($scope.files,function(file){
        fd.append('file',file);
        });
       $http.post('http://localhost:1337/mediaobject/upload',fd,
           {
               transformRequest: angular.identity,
               headers: {'Content-Type': undefined}                     
            }).success(function(d)
                {
                    console.log(d);
                })         
       }
     }]);

  </script>

Manoj Ojha
la source
9

L' <input type=file>élément ne fonctionne pas par défaut avec la directive ng-model . Il a besoin d'une directive personnalisée :

Démonstration de travail d'une select-ng-filesdirective qui fonctionne avec ng-model1

angular.module("app",[]);

angular.module("app").directive("selectNgFiles", function() {
  return {
    require: "ngModel",
    link: function postLink(scope,elem,attrs,ngModel) {
      elem.on("change", function(e) {
        var files = elem[0].files;
        ngModel.$setViewValue(files);
      })
    }
  }
});
<script src="//unpkg.com/angular/angular.js"></script>
  <body ng-app="app">
    <h1>AngularJS Input `type=file` Demo</h1>
    
    <input type="file" select-ng-files ng-model="fileList" multiple>
    
    <h2>Files</h2>
    <div ng-repeat="file in fileList">
      {{file.name}}
    </div>
  </body>


$http.postà partir d'une FileList

$scope.upload = function(url, fileList) {
    var config = { headers: { 'Content-Type': undefined },
                   transformResponse: angular.identity
                 };
    var promises = fileList.map(function(file) {
        return $http.post(url, file, config);
    });
    return $q.all(promises);
};

Lors de l'envoi d'un POST avec un objet File , il est important de définir 'Content-Type': undefined. La méthode d'envoi XHR détectera alors l' objet File et définira automatiquement le type de contenu.

georgeawg
la source
7

Facile avec une directive

Html:

<input type="file" file-upload multiple/>

JS:

app.directive('fileUpload', function () {
return {
    scope: true,        //create a new scope
    link: function (scope, el, attrs) {
        el.bind('change', function (event) {
            var files = event.target.files;
            //iterate files since 'multiple' may be specified on the element
            for (var i = 0;i<files.length;i++) {
                //emit event upward
                scope.$emit("fileSelected", { file: files[i] });
            }                                       
        });
    }
};

Dans la directive, nous nous assurons qu'une nouvelle portée est créée, puis écoutons les modifications apportées à l'élément d'entrée de fichier. Lorsque des modifications sont détectées avec émettre un événement vers toutes les étendues d'ancêtre (vers le haut) avec l'objet fichier comme paramètre.

Dans votre contrôleur:

$scope.files = [];

//listen for the file selected event
$scope.$on("fileSelected", function (event, args) {
    $scope.$apply(function () {            
        //add the file object to the scope's files collection
        $scope.files.push(args.file);
    });
});

Puis dans votre appel ajax:

data: { model: $scope.model, files: $scope.files }

http://shazwazza.com/post/uploading-files-and-json-data-in-the-same-request-with-angular-js/

Asher
la source
7

je pense que c'est le téléchargement de fichier angulaire:

ng-file-upload

Directive JS angulaire légère pour télécharger des fichiers.

Voici la page DEMO .

  • Prend en charge la progression du téléchargement, annuler / abandonner le téléchargement en cours, glisser-déposer des fichiers (html5), glisser-déposer du répertoire (webkit), les méthodes CORS, PUT (html5) / POST, validation du type et de la taille du fichier, afficher l'aperçu des images sélectionnées / audio / vidéos.
  • Téléchargement de fichiers multi-navigateur et FileReader (HTML5 et non HTML5) avec Flash polyfill FileAPI. Permet la validation / modification côté client avant de télécharger le fichier
  • Téléchargement direct sur les services db CouchDB, imgur, etc ... avec le type de contenu du fichier en utilisant Upload.http (). Cela permet un événement de progression pour les requêtes http POST / PUT angulaires.
  • Fichier shim séparé, les fichiers FileAPI sont chargés à la demande pour du code non HTML5, ce qui signifie aucune charge / code supplémentaire si vous avez juste besoin de la prise en charge HTML5.
  • Léger en utilisant $ http pour télécharger (avec shim pour les navigateurs non HTML5), donc toutes les fonctionnalités angulaires de $ http sont disponibles

https://github.com/danialfarid/ng-file-upload

Mohamad Shiralizadeh
la source
6

Votre fichier et les données json sont téléchargés en même temps.

// FIRST SOLUTION
 var _post = function (file, jsonData) {
            $http({
                url: your url,
                method: "POST",
                headers: { 'Content-Type': undefined },
                transformRequest: function (data) {
                    var formData = new FormData();
                    formData.append("model", angular.toJson(data.model));
                    formData.append("file", data.files);
                    return formData;
                },
                data: { model: jsonData, files: file }
            }).then(function (response) {
                ;
            });
        }
// END OF FIRST SOLUTION

// SECOND SOLUTION
// If you can add plural file and  If above code give an error.
// You can try following code
 var _post = function (file, jsonData) {
            $http({
                url: your url,
                method: "POST",
                headers: { 'Content-Type': undefined },
                transformRequest: function (data) {
                    var formData = new FormData();
                    formData.append("model", angular.toJson(data.model));
                for (var i = 0; i < data.files.length; i++) {
                    // add each file to
                    // the form data and iteratively name them
                    formData.append("file" + i, data.files[i]);
                }
                    return formData;
                },
                data: { model: jsonData, files: file }
            }).then(function (response) {
                ;
            });
        }
// END OF SECOND SOLUTION

barış çıracı
la source
4

Vous pouvez utiliser un FormDataobjet sûr et rapide:

// Store the file object when input field is changed
$scope.contentChanged = function(event){
    if (!event.files.length)
        return null;

    $scope.content = new FormData();
    $scope.content.append('fileUpload', event.files[0]); 
    $scope.$apply();
}

// Upload the file over HTTP
$scope.upload = function(){
    $http({
        method: 'POST', 
        url: '/remote/url',
        headers: {'Content-Type': undefined },
        data: $scope.content,
    }).success(function(response) {
        // Uploading complete
        console.log('Request finished', response);
    });
}
Farsheed
la source
Pouvez-vous également expliquer où «contentChanged» est utilisé exactement?
Marc J. Schmidt
Lorsqu'une entrée de fichier change, le déclenchement de cette fonction démarre le processus de téléchargement.
Farsheed
1
Puisqu'il n'y a pas <input type="file" ng-change="contentChanged($event)">, comment faire?
Marc J. Schmidt
3

http://jsfiddle.net/vishalvasani/4hqVu/ fonctionne très bien en chrome et IE (si vous mettez à jour CSS un peu en image de fond). Ceci est utilisé pour mettre à jour la barre de progression:

 scope.progress = Math.round(evt.loaded * 100 / evt.total)

mais dans FireFox, les données [pourcent] angulaires ne sont pas correctement mises à jour dans DOM, bien que les fichiers soient téléchargés avec succès.

mayankcpdixit
la source
Pour FF, vous pouvez écouter l' loadévénement et si la longueur est calculable, puis déclencher un événement de progression pour indiquer le téléchargement réussi. github.com/danialfarid/angular-file-upload s'occupe déjà de cela.
danial
Il est là, mais dans un violon donné, il est également vérifié et appliqué. Toujours pas d'espoir en FF.
mayankcpdixit
Je pense que si vous appelez simplement uploadProgress dans uploadComplete, cela devrait fonctionner pour FF
danial
NON, et même si c'est le cas, pouvez-vous expliquer pourquoi? J'ai donné un lien vers le violon dans mon post. Si possible, pouvez-vous le mettre à jour pour travailler dans FF et commenter le lien de la solution ici?
mayankcpdixit
Quelle version de Firefox?
danial
3

Vous pouvez envisager l'IaaS pour le téléchargement de fichiers, tel que Uploadcare . Il existe un package Angular pour cela: https://github.com/uploadcare/angular-uploadcare

Techniquement, il est implémenté en tant que directive, fournissant différentes options pour le téléchargement et les manipulations pour les images téléchargées dans le widget:

<uploadcare-widget
  ng-model="object.image.info.uuid"
  data-public-key="YOURKEYHERE"
  data-locale="en"
  data-tabs="file url"
  data-images-only="true"
  data-path-value="true"
  data-preview-step="true"
  data-clearable="true"
  data-multiple="false"
  data-crop="400:200"
  on-upload-complete="onUCUploadComplete(info)"
  on-widget-ready="onUCWidgetReady(widget)"
  value="{{ object.image.info.cdnUrl }}"
 />

Plus d'options de configuration pour jouer avec: https://uploadcare.com/widget/configure/

David Avsajanishvili
la source
3

Je sais que c'est une entrée tardive mais j'ai créé une simple directive de téléchargement. Que vous pouvez travailler en un rien de temps!

<input type="file" multiple ng-simple-upload web-api-url="/api/Upload" callback-fn="myCallback" />

ng-simple-upload plus sur Github avec un exemple utilisant l'API Web.

shammelburg
la source
3

HTML

<input type="file" id="file" name='file' onchange="angular.element(this).scope().profileimage(this)" />

ajoutez la méthode 'profileimage ()' à votre contrôleur

    $scope.profileimage = function(selectimage) {
      console.log(selectimage.files[0]);
 var selectfile=selectimage.files[0];
        r = new FileReader();
        r.onloadend = function (e) {
            debugger;
            var data = e.target.result;

        }
        r.readAsBinaryString(selectfile);
    }
Lakmi
la source
2

Cela devrait être une mise à jour / commentaire de la réponse de @ jquery-guru mais comme je n'ai pas assez de représentants, cela ira ici. Il corrige les erreurs qui sont maintenant générées par le code.

https://jsfiddle.net/vzhrqotw/

Le changement est essentiellement:

FileUploadCtrl.$inject = ['$scope']
function FileUploadCtrl(scope) {

À:

app.controller('FileUploadCtrl', function($scope)
{

N'hésitez pas à vous déplacer vers un endroit plus approprié si vous le souhaitez.

SKR
la source
2

J'ai lu tout le fil et la solution API HTML5 était la meilleure. Mais cela modifie mes fichiers binaires, les corrompant d'une manière que je n'ai pas étudiée. La solution qui a parfaitement fonctionné pour moi était:

HTML:

<input type="file" id="msds" ng-model="msds" name="msds"/>
<button ng-click="msds_update()">
    Upload
</button>

JS:

msds_update = function() {
    var f = document.getElementById('msds').files[0],
        r = new FileReader();
    r.onloadend = function(e) {
        var data = e.target.result;
        console.log(data);
        var fd = new FormData();
        fd.append('file', data);
        fd.append('file_name', f.name);
        $http.post('server_handler.php', fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
        .success(function(){
            console.log('success');
        })
        .error(function(){
            console.log('error');
        });
    };
    r.readAsDataURL(f);
}

Côté serveur (PHP):

$file_content = $_POST['file'];
$file_content = substr($file_content,
    strlen('data:text/plain;base64,'));
$file_content = base64_decode($file_content);
Camille Sauvage
la source
1

Je peux télécharger des fichiers en utilisant AngularJS en utilisant le code ci-dessous:

Le filepour l'argument qui doit être passé pour la fonction ngUploadFileUploadest $scope.fileselon votre question.

Le point clé ici est d'utiliser transformRequest: []. Cela empêchera $ http de jouer avec le contenu du fichier.

       function getFileBuffer(file) {
            var deferred = new $q.defer();
            var reader = new FileReader();
            reader.onloadend = function (e) {
                deferred.resolve(e.target.result);
            }
            reader.onerror = function (e) {
                deferred.reject(e.target.error);
            }

            reader.readAsArrayBuffer(file);
            return deferred.promise;
        }

        function ngUploadFileUpload(endPointUrl, file) {

            var deferred = new $q.defer();
            getFileBuffer(file).then(function (arrayBuffer) {

                $http({
                    method: 'POST',
                    url: endPointUrl,
                    headers: {
                        "accept": "application/json;odata=verbose",
                        'X-RequestDigest': spContext.securityValidation,
                        "content-length": arrayBuffer.byteLength
                    },
                    data: arrayBuffer,
                    transformRequest: []
                }).then(function (data) {
                    deferred.resolve(data);
                }, function (error) {
                    deferred.reject(error);
                    console.error("Error", error)
                });
            }, function (error) {
                console.error("Error", error)
            });

            return deferred.promise;

        }
Karthik
la source
0

La réponse acceptée ci-dessus n'est pas compatible avec le navigateur. Si quelqu'un a un problème de compatibilité, essayez ceci.

Violon

Afficher le code

 <div ng-controller="MyCtrl">
      <input type="file" id="file" name="file"/>
      <br>
      <button ng-click="add()">Add</button>
      <p>{{data}}</p>
    </div>

Code contrôleur

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.data = 'none';    
    $scope.add = function(){
      var f = document.getElementById('file').files[0],
          r = new FileReader();
      r.onloadend = function(e){        
          var binary = "";
var bytes = new Uint8Array(e.target.result);
var length = bytes.byteLength;

for (var i = 0; i < length; i++) 
{
    binary += String.fromCharCode(bytes[i]);
}

$scope.data = (binary).toString();

          alert($scope.data);
      }
      r.readAsArrayBuffer(f);
    }
}
Kurkula
la source
0

en mots simples

en Html - ajoutez le code ci-dessous uniquement

     <form name="upload" class="form" data-ng-submit="addFile()">
  <input type="file" name="file" multiple 
 onchange="angular.element(this).scope().uploadedFile(this)" />
 <button type="submit">Upload </button>
</form>

dans le contrôleur - Cette fonction est appelée lorsque vous cliquez sur " bouton de téléchargement de fichier" . il téléchargera le fichier. vous pouvez le consoler.

$scope.uploadedFile = function(element) {
$scope.$apply(function($scope) {
  $scope.files = element.files;         
});
}

ajouter plus dans les contrôleurs - sous le code ajouter dans la fonction. Cette fonction est appelée lorsque vous cliquez sur le bouton qui est utilisé "frapper l'API (POST)" . il enverra le fichier (qui a téléchargé) et les données du formulaire au backend.

var url = httpURL + "/reporttojson"
        var files=$scope.files;

         for ( var i = 0; i < files.length; i++)
         {
            var fd = new FormData();
             angular.forEach(files,function(file){
             fd.append('file',file);
             });
             var data ={
              msg : message,
              sub : sub,
              sendMail: sendMail,
              selectUsersAcknowledge:false
             };

             fd.append("data", JSON.stringify(data));
              $http.post(url, fd, {
               withCredentials : false,
               headers : {
                'Content-Type' : undefined
               },
             transformRequest : angular.identity
             }).success(function(data)
             {
                  toastr.success("Notification sent successfully","",{timeOut: 2000});
                  $scope.removereport()
                   $timeout(function() {
                    location.reload();
                }, 1000);

             }).error(function(data)
             {
              toastr.success("Error in Sending Notification","",{timeOut: 2000});
              $scope.removereport()
             });
        }

dans ce cas .. j'ai ajouté le code ci-dessous comme données de formulaire

var data ={
          msg : message,
          sub : sub,
          sendMail: sendMail,
          selectUsersAcknowledge:false
         };
Shashwat Gupta
la source
0
<form id="csv_file_form" ng-submit="submit_import_csv()" method="POST" enctype="multipart/form-data">
    <input ng-model='file' type="file"/>
    <input type="submit" value='Submit'/>
</form>

Dans le contrôleur angularJS

$scope.submit_import_csv = function(){

        var formData = new FormData(document.getElementById("csv_file_form"));
        console.log(formData);

        $.ajax({
            url: "import",
            type: 'POST',
            data:  formData,
            mimeType:"multipart/form-data",
            contentType: false,
            cache: false,
            processData:false,
            success: function(result, textStatus, jqXHR)
            {
            console.log(result);
            }
        });

        return false;
    }
rubyshine72
la source
0

Nous avons utilisé HTML, CSS et AngularJS. L'exemple suivant montre comment télécharger le fichier à l'aide d'AngularJS.

<html>

   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
   </head>

   <body ng-app = "myApp">

      <div ng-controller = "myCtrl">
         <input type = "file" file-model = "myFile"/>
         <button ng-click = "uploadFile()">upload me</button>
      </div>

      <script>
         var myApp = angular.module('myApp', []);

         myApp.directive('fileModel', ['$parse', function ($parse) {
            return {
               restrict: 'A',
               link: function(scope, element, attrs) {
                  var model = $parse(attrs.fileModel);
                  var modelSetter = model.assign;

                  element.bind('change', function(){
                     scope.$apply(function(){
                        modelSetter(scope, element[0].files[0]);
                     });
                  });
               }
            };
         }]);

         myApp.service('fileUpload', ['$http', function ($http) {
            this.uploadFileToUrl = function(file, uploadUrl){
               var fd = new FormData();
               fd.append('file', file);

               $http.post(uploadUrl, fd, {
                  transformRequest: angular.identity,
                  headers: {'Content-Type': undefined}
               })

               .success(function(){
               })

               .error(function(){
               });
            }
         }]);

         myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
            $scope.uploadFile = function(){
               var file = $scope.myFile;

               console.log('file is ' );
               console.dir(file);

               var uploadUrl = "/fileUpload";
               fileUpload.uploadFileToUrl(file, uploadUrl);
            };
         }]);

      </script>

   </body>
</html>
Jignesh Mesvaniya
la source
Cela vient de TutorialsPoint , mais au moins vous avez fait du bon travail en corrigeant leur exemple, qui ne peut même pas fonctionner à cause d'erreurs évidentes!
Benito
0

Exemple de travail utilisant une directive simple ( modèle de fichier ng ):

.directive("ngFileModel", [function () {
  return {
      $scope: {
          ngFileModel: "="
      },
      link: function ($scope:any, element, attributes) {
          element.bind("change", function (changeEvent:any) {
              var reader = new FileReader();
              reader.onload = function (loadEvent) {
                  $scope.$apply(function () {
                      $scope.ngFileModel = {
                          lastModified: changeEvent.target.files[0].lastModified,
                          lastModifiedDate: changeEvent.target.files[0].lastModifiedDate,
                          name: changeEvent.target.files[0].name,
                          size: changeEvent.target.files[0].size,
                          type: changeEvent.target.files[0].type,
                          data: changeEvent.target.files[0]
                      };
                  });
              }
              reader.readAsDataURL(changeEvent.target.files[0]);
          });
      }
  }
}])

et utilisez FormDatapour télécharger le fichier dans votre fonction.

var formData = new FormData();
 formData.append("document", $scope.ngFileModel.data)
 formData.append("user_id", $scope.userId)

tous les crédits vont pour https://github.com/mistralworks/ng-file-model

J'ai rencontré un petit problème, vous pouvez le vérifier ici: https://github.com/mistralworks/ng-file-model/issues/7

Enfin, voici un dépôt fourchu: https://github.com/okasha93/ng-file-model/blob/patch-1/ng-file-model.js

Abdallah Okasha
la source
0

Le code aidera à insérer le fichier

<body ng-app = "myApp">
<form ng-controller="insert_Ctrl"  method="post" action=""  name="myForm" enctype="multipart/form-data" novalidate>
    <div>
        <p><input type="file" ng-model="myFile" class="form-control"  onchange="angular.element(this).scope().uploadedFile(this)">
            <span style="color:red" ng-show="(myForm.myFile.$error.required&&myForm.myFile.$touched)">Select Picture</span>
        </p>
    </div>
    <div>
        <input type="button" name="submit"  ng-click="uploadFile()" class="btn-primary" ng-disabled="myForm.myFile.$invalid" value="insert">
    </div>
</form>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> 
<script src="insert.js"></script>
</body>

insert.js

var app = angular.module('myApp',[]);
app.service('uploadFile', ['$http','$window', function ($http,$window) {
    this.uploadFiletoServer = function(file,uploadUrl){
        var fd = new FormData();
        fd.append('file', file);
        $http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
        .success(function(data){
            alert("insert successfull");
            $window.location.href = ' ';//your window location
        })
        .error(function(){
            alert("Error");
        });
    }
}]);
app.controller('insert_Ctrl',  ['$scope', 'uploadFile', function($scope, uploadFile){
    $scope.uploadFile = function() {
        $scope.myFile = $scope.files[0];
        var file = $scope.myFile;
        var url = "save_data.php";
        uploadFile.uploadFiletoServer(file,url);
    };
    $scope.uploadedFile = function(element) {
        var reader = new FileReader();
        reader.onload = function(event) {
            $scope.$apply(function($scope) {
                $scope.files = element.files;
                $scope.src = event.target.result  
            });
        }
        reader.readAsDataURL(element.files[0]);
    }
}]);

save_data.php

<?php
    require "dbconnection.php";
    $ext = pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION);
    $image = time().'.'.$ext;
    move_uploaded_file($_FILES["file"]["tmp_name"],"upload/".$image);
    $query="insert into test_table values ('null','$image')";
    mysqli_query($con,$query);
?>
Hajis Hakkim
la source
0

cela marche

file.html

<html>
   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
   </head>
   <body ng-app = "app">
      <div ng-controller = "myCtrl">
         <input type = "file" file-model = "myFile"/>
         <button ng-click = "uploadFile()">upload me</button>
      </div>
   </body>
   <script src="controller.js"></script>
</html>

controller.js

     var app = angular.module('app', []);

     app.service('fileUpload', ['$http', function ($http) {
        this.uploadFileToUrl = function(file, uploadUrl){
           var fd = new FormData();
           fd.append('file', file);

           $http.post(uploadUrl, fd, {
              transformRequest: angular.identity,
              headers: {'Content-Type': undefined}
           }).success(function(res){
                console.log(res);
           }).error(function(error){
                console.log(error);
           });
        }
     }]);

     app.controller('fileCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
        $scope.uploadFile = function(){
           var file = $scope.myFile;

           console.log('file is ' );
           console.dir(file);

           var uploadUrl = "/fileUpload.php";  // upload url stands for api endpoint to handle upload to directory
           fileUpload.uploadFileToUrl(file, uploadUrl);
        };
     }]);

  </script>

fileupload.php

  <?php
    $ext = pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION);
    $image = time().'.'.$ext;
    move_uploaded_file($_FILES["file"]["tmp_name"],__DIR__. ' \\'.$image);
  ?>
Adeojo Emmanuel IMM
la source
0

TÉLÉCHARGER DES FICHIERS

<input type="file" name="resume" onchange="angular.element(this).scope().uploadResume()" ng-model="fileupload" id="resume" />


        $scope.uploadResume = function () { 
            var f = document.getElementById('resume').files[0];
            $scope.selectedResumeName = f.name;
            $scope.selectedResumeType = f.type;
            r = new FileReader();

            r.onloadend = function (e) { 
                $scope.data = e.target.result;
            }

            r.readAsDataURL(f);

        };

TELECHARGER DES FICHIERS:

          <a href="{{applicant.resume}}" download> download resume</a>

var app = angular.module("myApp", []);

            app.config(['$compileProvider', function ($compileProvider) {
                $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension):/);
                $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|local|data|chrome-extension):/);

            }]);
DC
la source
-1
app.directive('ngUpload', function () {   
  return {    
    restrict: 'A',  
    link: function (scope, element, attrs) {

      var options = {};
      options.enableControls = attrs['uploadOptionsEnableControls'];

      // get scope function to execute on successful form upload
      if (attrs['ngUpload']) {

        element.attr("target", "upload_iframe");
        element.attr("method", "post");

        // Append a timestamp field to the url to prevent browser caching results
        element.attr("action", element.attr("action") + "?_t=" + new Date().getTime());

        element.attr("enctype", "multipart/form-data");
        element.attr("encoding", "multipart/form-data");

        // Retrieve the callback function
        var fn = attrs['ngUpload'].split('(')[0];
        var callbackFn = scope.$eval(fn);
        if (callbackFn == null || callbackFn == undefined || !angular.isFunction(callbackFn))
        {
          var message = "The expression on the ngUpload directive does not point to a valid function.";
          // console.error(message);
          throw message + "\n";
        }                      

        // Helper function to create new  i frame for each form submission
        var addNewDisposableIframe = function (submitControl) {
          // create a new iframe
          var iframe = $("<iframe id='upload_iframe' name='upload_iframe' border='0' width='0' height='0' style='width: 0px; height: 0px;
border: none; display: none' />");

          // attach function to load event of the iframe
          iframe.bind('load', function () {

              // get content - requires jQuery
              var content = iframe.contents().find('body').text();

              // execute the upload response function in the active scope
              scope.$apply(function () { callbackFn(content, content !== "" /* upload completed */); });

              // remove iframe
              if (content != "") // Fixes a bug in Google Chrome that dispose the iframe before content is ready.
                setTimeout(function () { iframe.remove(); }, 250);


              submitControl.attr('disabled', null);
              submitControl.attr('title', 'Click to start upload.');
            });

          // add the new iframe to application
          element.parent().append(iframe);
        };

        // 1) get the upload submit control(s) on the form (submitters must be decorated with the 'ng-upload-submit' class)
        // 2) attach a handler to the controls' click event
        $('.upload-submit', element).click(
          function () {

            addNewDisposableIframe($(this) /* pass the submit control */);

            scope.$apply(function () { callbackFn("Please wait...", false /* upload not completed */); });



            var enabled = true;
            if (options.enableControls === null || options.enableControls === undefined || options.enableControls.length >= 0) {
              // disable the submit control on click
              $(this).attr('disabled', 'disabled');
              enabled = false;
            }

            $(this).attr('title', (enabled ? '[ENABLED]: ' : '[DISABLED]: ') + 'Uploading, please wait...');

            // submit the form
            $(element).submit();
          }
        ).attr('title', 'Click to start upload.');
      }
      else
        alert("No callback function found on the ngUpload directive.");     
    }   
  }; 
});



<form class="form form-inline" name="uploadForm" id="uploadForm"
ng-upload="uploadForm12"  action="rest/uploadHelpFile"  method="post"
enctype="multipart/form-data" style="margin-top: 3px;margin-left:
6px"> <button type="submit" id="mbUploadBtn" class="upload-submit"
ng-hide="true"></button> </form>

@RequestMapping(value = "/uploadHelpFile", method =
RequestMethod.POST)   public @ResponseBody String
uploadHelpFile(@RequestParam(value = "file") CommonsMultipartFile[]
file,@RequestParam(value = "fileName") String
fileName,@RequestParam(value = "helpFileType") String
helpFileType,@RequestParam(value = "helpFileName") String
helpFileName) { }
Rajasekhar T
la source
veuillez formater votre réponse, elle n'est pas au bon format
Saineshwar