2013-05-16 12 views
11

Próbuję uzyskać kątowy odczyt zawartości pliku, który użytkownik wybiera za pomocą kontrolki <input type="file". Nawet jeśli nie ma kątowy wytyczne dotyczące kontroli przesyłania plików, to powinno być łatwe do ustalenia, że ​​przy wywołaniu $apply:Przesyłanie pliku HTML5 za pomocą AngularJS

function MyController($scope) { 
    $('#myFile').on('change', function() { 
    var that = this; 
    $scope.$apply(function() { $scope.files = that.files }); 
    }); 
} 

Niestety, zdarzenie nie jest zwolniony. To tak, jakby selektor nie mógł odwołać się do prawidłowego elementu DOM: mimo że selektor znajduje element, lista plików jest zawsze pusta. Zdarza się to również, gdy przeglądam konsolę js. Inspektor DOM zamiast tego ma listę plików wśród swoich właściwości.

To doprowadza mnie do szału, ale jedyny sposób, w jaki mam to do tej pory, to użycie wbudowanej obsługi zdarzeń, która przypisuje zmienną globalną. Dlaczego selektor jquery zwraca inny element? Czy jest jakaś kompilacja szablonów, mumbo-jumbo, która powoduje, że mylić selektory?

Odpowiedz

14

Oto co robię:

http://plnkr.co/edit/JPxSCyrxosVXfZnzEIuS?p=preview

app.directive('filelistBind', function() { 
    return function(scope, elm, attrs) { 
    elm.bind('change', function(evt) { 
     scope.$apply(function() { 
     scope[ attrs.name ] = evt.target.files; 
     console.log(scope[ attrs.name ]); 
     }); 
    }); 
    }; 
}); 

szablon:

<input type="file" filelist-bind name="files"/> 
<p>selected files : <pre>{{ files | json }}</pre></p> 

Tego rodzaju zadania, na pewno chcą skorzystać z dyrektywy. Ale myślę, że twoim głównym zmartwieniem jest, jak uzyskać dostęp do wybranych plików obiektów i mój przykład powinien to wyjaśnić.

+0

ładny. Zakończyłem definiując globalną funkcję w kontrolerze i wywołując ją z wbudowanego modułu obsługi zdarzeń. Ponieważ zakres $ jest w zewnętrznym zamknięciu, przynajmniej mogę $ zastosować zmiany. Dyrektywa jest zdecydowanie bardziej "kanciastym" sposobem na zrobienie tego. Ale pytanie brzmi: dlaczego selektor zwraca element 'input', który wygląda dokładnie tak, jak ten, z którym użytkownik wchodzi w interakcję, ale tak naprawdę nie jest? – BruceBerry

+0

mmmh to nie działa dla mnie. jeśli uruchomię twój plunkr, zawsze otrzymuję pliki : { "0": {} } czy coś nie tak? – pomarc

+0

@pomarc IIRC, kiedyś działało ... Wygląda jednak na to, że nowoczesne przeglądarki nie obsługują wiązania obiektu File. Musisz bezpośrednio uzyskać dostęp do właściwości, aby pokazać je w widoku. – Tosh

2

Jeśli szukasz przesyłania plików z kątową można użyć tej wtyczki

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

Jest to w gruncie dyrektywy jak odpowiedź Tosh, że dba o przeglądarkach bez HTML5 z FileAPI rzutowej PolyFill i ma $ Funkcja http.uploadFile do przesłania rzeczywistego pliku za pośrednictwem AJAX.

1

Ten site używa usługi Angular do przesyłania plików HTML5. Prostym sposobem jest skonfigurowanie kontrolera, który wywołuje usługę i aktualizuje interfejs użytkownika po zakończeniu wywołania asynchronicznego.

kontroler:

myapp.controller('fileUploadCtrl', ['$scope', '$q', 'FileInputService', function ($scope, $q, FileInputService) { 
      $scope.fileInputContent = ""; 
      $scope.onFileUpload = function (element) { 
       $scope.$apply(function (scope) { 
        var file = element.files[0]; 
        FileInputService.readFileAsync(file).then(function (fileInputContent) { 
         $scope.fileInputContent = fileInputContent; 
        }); 
       }); 
      }; 
     }]); 

usługa:

myapp.service('FileInputService', function ($q) { 

    this.readFileAsync = function (file) { 
     var deferred = $q.defer(), 
     fileReader = new FileReader(), 
     fileReader.readAsText(file); 

     fileReader.onload = function (e) { 
      deferred.resolve(e.target.result); 
     }; 
     return deferred.promise; 
    }; 
}); 

szablon:

Choose File <input type="file" onchange="angular.element(this).scope().onFileUpload(this)"> 
<br /> 
{{fileInputContent}} 

referencyjny: można znaleźć pełny kod źródłowy i odniesienie on this site.

Powiązane problemy