Загрузка файла HTML5 с помощью AngularJS

Я пытаюсь получить angular для чтения содержимого файла, который пользователь выбирает с помощью элемента управления <input type="file". Несмотря на то, что angular не имеет директив для элементов управления загрузкой файлов, должно быть легко исправить это с помощью вызова $apply:

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

К сожалению, событие никогда не запускается. Он, как и селектор, не может ссылаться на правильный элемент DOM: даже если селектор находит элемент, список файлов всегда пуст. Это также происходит, если я сошлюсь с консолью js. Вместо этого инспектор DOM имеет список файлов среди своих свойств.

Это сводит меня с ума, но единственный способ заставить его работать до сих пор - использовать встроенный обработчик событий, который присваивает глобальную переменную. Почему селектор jquery возвращает другой элемент? Есть ли какая-то компиляция шаблона mumbo-jumbo, что angular делает, что путает селекторов?

Ответ 1

Вот что я делаю:

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

шаблон:

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

Эта задача, вы определенно хотите использовать директиву. Но я думаю, что ваша главная проблема заключается в том, как получить доступ к выбранному файлу объекты и мой пример должны уточнить это.

Ответ 2

Если вы ищете загрузку файла с помощью angular, вы можете использовать этот плагин

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

В основном это директива типа tosh answer, которая заботится о браузерах, отличных от HTML5, с файловым flash файлом polyfill и имеет функцию $http.uploadFile для загрузки фактического файла через AJAX.

Ответ 3

Этот сайт использует службу Angular для загрузки файлов HTML5. Простым способом является настройка контроллера, который вызывает службу и обновляет пользовательский интерфейс при завершении асинхронного вызова.

контроллер:

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

службы:

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

:

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

Ссылка: Вы можете найти полный исходный код и ссылку на этом сайте.