Przesyłanie plików za pomocą AngularJS


296

Oto moja forma HTML:

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

Chcę załadować obraz z komputera lokalnego i chcę przeczytać zawartość przesłanego pliku. Wszystko to chcę zrobić za pomocą AngularJS.

Kiedy próbuję wydrukować, jego wartość $scope.filejest nieokreślona.



Odpowiedzi:


344

Niektóre odpowiedzi tutaj proponują użycie FormData(), ale niestety jest to obiekt przeglądarki niedostępny w Internet Explorerze 9 i niższych. Jeśli potrzebujesz obsługi tych starszych przeglądarek, potrzebujesz strategii tworzenia kopii zapasowych, takiej jak przy użyciu <iframe>lub Flash.

Istnieje już wiele modułów Angular.js do przesyłania plików. Te dwa mają wyraźne wsparcie dla starszych przeglądarek:

I kilka innych opcji:

Jeden z nich powinien pasować do twojego projektu lub może dać ci wgląd w to, jak samemu go zakodować.


4
Jeszcze jedno rozwiązanie (IaaS do przesyłania plików): github.com/uploadcare/angular-uploadcare
David Avsajanishvili,

27
EggHead ma dobre wideo na ten temat - egghead.io/lessons/angularjs-file-uploads
Adam Zerner

2
danialfarid / angular-file-upload zostaje przemianowany na ng-file-upload
Michael

5
3-letnia odpowiedź. IE 9 jest teraz
martwy

5
Myślę, że powinieneś zaktualizować swoją odpowiedź, aby mieć właściwe rozwiązanie zamiast wskazywać linki. To sposób przepełnienia stosu. W przeciwnym razie po prostu zrób to jako komentarz.
Alex Reynolds,

178

Najłatwiej jest użyć interfejsu API HTML5, a mianowicie FileReader

HTML jest dość prosty:

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

W kontrolerze zdefiniuj metodę „dodaj”:

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

Kompatybilność z przeglądarkami

Przeglądarki stacjonarne

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

Przeglądarki mobilne

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

Uwaga: metoda readAsBinaryString () jest przestarzała i zamiast niej należy użyć metody readAsArrayBuffer () .


10
FileReader to klasa ze standardowego interfejsu API plików HTML5 w3.org/TR/FileAPI . Pozwala odczytać dane z pliku określonego w elemencie wejściowym HTML i przetworzyć je w onloadendfunkcji wywołania zwrotnego. Nie potrzebujesz żadnej biblioteki, aby korzystać z tego API, jest już w przeglądarce (chyba że używasz bardzo starej). Mam nadzieję że to pomoże.
yagger

15
FileReader.readAsBinaryString jest przestarzałe od 12 lipca 2012 Robocza wersja robocza z W3C.
Shane Stillwell

13
Nie powinieneś uzyskiwać dostępu do DOM za pomocą kątownika. To bardzo zła praktyka.
jeanmatthieud

9
@Siderex, nie w kontrolerze, ale wspaniale jest to zrobić z dyrektywy. Właśnie do tego służą dyrektywy. Możesz o tym przeczytać w Angular docs docs.quarejs.org/guide/directive
yagger

1
@yagger czy istnieje szczególny powód, dla którego twoje linki odwołują się do readAsArrayBuffermetody FileReaderSync (która jest dostępna tylko w robotach sieciowych) zamiast zwykłego, asynchronicznego interfejsu API FileReader ?
doldt

58

Jest to nowoczesny sposób przeglądarki, bez bibliotek stron trzecich. Działa na wszystkich najnowszych przeglądarkach.

 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 (tylko front-end) https://jsfiddle.net/vince123/8d18tsey/31/


Jak pobrać plik w węźle?
Juicy

Jakieś szczegóły? Potrzebujesz akcji ng-submitlub formularza? To samo z siebie nic nie robi
Aron

@Emaborsa hello Dodałem jsfiddle i stworzyłem pełniejszy przykład kodu php. Przesyła obraz po zmianie wartości wejściowej pliku, więc nie jest wymagane przesyłanie ng.
Vince Verhoeven

Idealne najprostsze rozwiązanie, ale zajęło mi wieki, aby dowiedzieć się, jak zmusić moje usługi WCF do radzenia sobie z przesyłanymi danymi. Jest to istotne , aby podjąć strumienia danych i przekazać go przez coś podobnego MultiParser właściwie odczytywać dane pliku: stackoverflow.com/a/23702692/391605 Inaczej będziesz przechowywania surowych bajtów „------ WebKitFormBoundary Treść-usposobienie: ... itd. ”
Mike Gledhill

Musiałem dodać właściwość „transformRequest: angular.identity” do obiektu żądania $ http, jak pokazał Manoy Ojha trochę dalej, w przeciwnym razie Typ treści nie byłby ustawiony poprawnie i przykład nie działałby.
Gregor Slavec

38

Poniżej znajduje się przykładowy przykład przesłania pliku:

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

W tej jednej funkcji o nazwie

setFiles

Z widoku, który zaktualizuje tablicę plików w kontrolerze

lub

Możesz sprawdzić przesyłanie plików jQuery za pomocą AngularJS

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


Cześć, szukałem czegoś, przez co mogę po prostu załadować jeden plik i wyświetlić tuż pod nim. Jednak w twoim przykładzie nie byłem w stanie zrobić tego samego. Nie przejmuj się, ale jestem nowy w tych angularjach i mam zamiar nauczyć się realizować ten konkretny cel w prostszy, ale solidny sposób.
Aditya Sethi,

To bardzo pomogło. Dzięki!
RachelD

Doskonały przykład bez użycia dodatkowej biblioteki / rozszerzenia. Dzięki.
markdsievers

4
Bardzo pomocna, tylko uwaga ... używa interfejsu API File, który nie działa w IE9 lub niższej
ArjaaAine

Masz pomysł, jak uzyskać błędy z wyniku? Serwer może wyrzucić błąd i chciałbym wyświetlić ten komunikat o błędzie ...
CularBytes

17

Można osiągnąć piękny plik i folder przesyłać za pomocą flow.js .

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

Sprawdź demo tutaj

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

Nie obsługuje IE7, IE8, IE9, więc w końcu będziesz musiał użyć warstwy kompatybilności

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


`flow.js 'jest fantastyczny, ale brakuje mu jeszcze dokumentacji. Potrzebuję zmanipulować pojedyncze przesłanie i dodać podgląd, a także osobno wysłać przycisk zdarzenia, ale nie wiem, jak to zrobić.
Francis Rodrigues,

14

Użyj onchangezdarzenia, aby przekazać element pliku wejściowego do funkcji.

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

Tak więc, gdy użytkownik wybiera plik, masz do niego odniesienie, bez konieczności klikania przycisku „Dodaj” lub „Prześlij”.

$scope.fileSelected = function (element) {
    var myFileSelected = element.files[0];
};

2
To nie działa zgodnie z oczekiwaniami. Oto mój przepływ pracy: 1. Odśwież stronę 2. Dodaj nowy plik. ** Pierwszy dodany plik jest zawsze niezdefiniowany. ** 3. Dodaj kolejny plik. Od teraz każdy przesłany plik jest poprzednim plikiem, który dodałem. Tak więc dla drugiego pliku, który dodam, załadowałbym pierwszy plik, który dodałem (który faktycznie nie powiódł się)
Pulkit Pahwa

1
najlepsza metoda!
Stepan Yakovenko

11

Wypróbowałem wszystkie alternatywy, które daje @Anoyz (poprawna odpowiedź) ... a najlepszym rozwiązaniem jest https://github.com/danialfarid/angular-file-upload

Niektóre funkcje:

  • Postęp
  • Multifile
  • Pola
  • Stare przeglądarki (IE8-9)

Dla mnie działa dobrze. Musisz tylko zwrócić uwagę na instrukcje.

Po stronie serwera używam oprogramowania pośredniego NodeJs, Express 4 i Multer do zarządzania żądaniami wieloczęściowymi.


Jak wyświetlasz obrazy? Z backendu z powodzeniem wchodzą, ale są zapisywane jako, nlzt9LJWRrAZEO3ZteZUOgGcale bez formatu .png. Jak to dodać?
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>

Skrypty

  <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>


9

<input type=file>Element nie domyślnie pracy z dyrektywą ng-modelu . Potrzebuje niestandardowej dyrektywy :

Demonstracja robocza select-ng-filesdyrektywy, która działa z 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.postz listy plików

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

Podczas wysyłania testu POST z obiektem File należy ustawić 'Content-Type': undefined. Metoda wysyłania XHR wykryje wówczas obiekt File i automatycznie ustawi typ zawartości.


7

Łatwe dzięki dyrektywie

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

W dyrektywie zapewniamy utworzenie nowego zakresu, a następnie nasłuchujemy zmian wprowadzonych w elemencie wejściowym pliku. Po wykryciu zmian emituj zdarzenie do wszystkich zakresów przodków (w górę) z obiektem pliku jako parametrem.

W twoim kontrolerze:

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

Następnie w wywołaniu ajax:

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

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


7

myślę, że jest to przesyłanie pliku kątowego:

przesyłanie pliku ng

Lekka dyrektywa Angular JS do przesyłania plików.

Oto DEMO page.Features

  • Obsługuje postęp przesyłania, anuluj / przerwij przesyłanie w trakcie, przeciągnij i upuść plik (html5), przeciągnij i upuść katalog (webkit), metody CORS, PUT (html5) / POST, sprawdzanie poprawności typu i rozmiaru pliku, wyświetl podgląd wybranych zdjęć / audio / wideo.
  • Przesyłanie plików między przeglądarkami i FileReader (HTML5 i nie HTML5) z Flash FileFI FileFill. Umożliwia walidację / modyfikację po stronie klienta przed przesłaniem pliku
  • Bezpośrednie przesyłanie do usług db CouchDB, imgur itp. Z typem zawartości pliku za pomocą Upload.http (). Umożliwia to zdarzenie postępu dla kątowych żądań HTTP POST / PUT.
  • Oddzielny plik podkładki, pliki FileAPI są ładowane na żądanie dla kodu innego niż HTML5, co oznacza brak dodatkowego ładowania / kodu, jeśli potrzebujesz tylko obsługi HTML5.
  • Lekki przy użyciu zwykłego $ http do przesyłania (z podkładką dla przeglądarek nieobsługujących HTML5), dzięki czemu wszystkie funkcje $ http kątowe są dostępne

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


6

Przesyłanie pliku i danych json w tym samym czasie.

// 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


4

Możesz użyć FormDataobiektu, który jest bezpieczny i szybki:

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

Czy możesz również wyjaśnić, gdzie dokładnie używa się „contentChanged”?
Marc J. Schmidt,

Gdy dane wejściowe pliku ulegną zmianie, uruchomienie tej funkcji rozpocznie proces przesyłania.
Farsheed,

1
Skoro nie ma <input type="file" ng-change="contentChanged($event)">, jak to zrobić?
Marc J. Schmidt,

3

http://jsfiddle.net/vishalvasani/4hqVu/ działa dobrze w Chrome i IE (jeśli zaktualizujesz CSS trochę w obrazie tła). Służy to do aktualizacji paska postępu:

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

ale w FireFox dane [procentowe] programu angular nie zostały pomyślnie zaktualizowane w DOM, chociaż pliki są ładowane pomyślnie.


W przypadku FF można odsłuchać loadzdarzenie, a jeśli długość można obliczyć, uruchom zdarzenie postępu, aby wskazać pomyślne przesłanie. Github.com/danialfarid/angular-file-upload już się tym zajmuje.
Danial

Jest tam, ale w danym skrzypcach jest również sprawdzane i stosowane. Nadal nie ma nadziei w FF.
mayankcpdixit

Myślę, że jeśli po prostu zadzwonisz do uploadProgress w uploadComplete, to powinno działać dla FF
Danial

NIE, nie ma, a nawet jeśli tak, czy możesz wyjaśnić, dlaczego? W swoim poście podaję link do skrzypiec. Jeśli to możliwe, możesz zaktualizować go do działania w FF i skomentować link do rozwiązania tutaj?
mayankcpdixit

Jaka wersja przeglądarki Firefox?
Danial

3

Możesz rozważyć IaaS do przesyłania plików, na przykład Uploadcare . Jest do tego pakiet Angular: https://github.com/uploadcare/angular-uploadcare

Technicznie jest on implementowany jako dyrektywa, zapewniając różne opcje przesyłania i manipulowania przesłanymi obrazami w widżecie:

<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 }}"
 />

Więcej opcji konfiguracji do zabawy: https://uploadcare.com/widget/configure/


3

Wiem, że to późny wpis, ale stworzyłem prostą dyrektywę przesyłania. Które możesz zacząć pracować w mgnieniu oka!

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

ng-simple-upload więcej na Github na przykładzie z interfejsem API sieci Web.


3

HTML

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

dodaj metodę „profileimage ()” do kontrolera

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

2

To powinna być aktualizacja / komentarz do odpowiedzi @ jquery-guru, ale ponieważ nie mam wystarczającej liczby powtórzeń, trafi tutaj. Naprawia błędy, które są teraz generowane przez kod.

https://jsfiddle.net/vzhrqotw/

Zmiana polega zasadniczo na:

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

Do:

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

W razie potrzeby możesz przenieść się w bardziej odpowiednie miejsce.


2

Przeczytałem cały wątek, a interfejs API HTML5 wyglądał najlepiej. Ale zmienia moje pliki binarne, niszcząc je w sposób, którego nie zbadałem. Idealnym rozwiązaniem dla mnie było:

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

Po stronie serwera (PHP):

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

1

Jestem w stanie przesyłać pliki za pomocą AngularJS, używając poniższego kodu:

The fileDo argumentu, że musi zostać przekazany do funkcji ngUploadFileUploadjest $scope.filejak na swoje pytanie.

Kluczową kwestią jest tutaj użycie transformRequest: []. Zapobiegnie to $ http z bałaganem z zawartością pliku.

       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;

        }

0

Powyższa odpowiedź nie jest kompatybilna z przeglądarką. Jeśli ktoś ma problem ze zgodnością, spróbuj tego.

Skrzypce

Wyświetl kod

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

Kod kontrolera

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

0

w prostych słowach

w HTML - dodaj tylko poniższy kod

     <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>

w kontrolerze - Ta funkcja jest wywoływana po kliknięciu przycisku „Prześlij plik” . prześle plik. możesz to pocieszyć.

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

dodaj więcej w kontrolerach - poniżej kodu dodaj do funkcji. Ta funkcja jest wywoływana po kliknięciu przycisku „Uderzenie w API (POST)” . wyśle ​​plik (który przesłał) i dane formularza do backendu.

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

w tym przypadku .. dodałem poniższy kod jako dane formularza

var data ={
          msg : message,
          sub : sub,
          sendMail: sendMail,
          selectUsersAcknowledge:false
         };

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>

W sterowniku 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;
    }

0

Użyliśmy HTML, CSS i AngularJS. Poniższy przykład pokazuje, jak przesłać plik za pomocą 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>

Pochodzi z TutorialsPoint , ale przynajmniej wykonałeś dobrą robotę, poprawiając ich przykład, który nie może działać nawet z powodu oczywistych błędów!
Benito,

0

Przykład roboczy z użyciem prostej dyrektywy ( model pliku 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]);
          });
      }
  }
}])

i użyj, FormDataaby przesłać plik w swojej funkcji.

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

wszystkie kredyty dotyczą https://github.com/mistralworks/ng-file-model

Napotkałem mały problem, który możesz sprawdzić tutaj: https://github.com/mistralworks/ng-file-model/issues/7

Wreszcie, oto rozwidlone repozytorium: https://github.com/okasha93/ng-file-model/blob/patch-1/ng-file-model.js


0

Kod pomoże wstawić plik

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

0

to działa

plik.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);
  ?>

0

PRZEŚLIJ PLIKI

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

        };

POBIERZ PLIKI:

          <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):/);

            }]);

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

proszę sformatować odpowiedź, która nie jest w odpowiednim formacie
Saineshwar,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.