Отображение выбранного файла из <input> в AngularJS

0

У меня есть рабочий пример с использованием стандартного Javascript, но я хотел бы сделать эту работу более естественной с помощью AngularJS.

В частности, мне нужно обновить span с именем файла, выбранного пользователем.

Вот что я реализовал с использованием собственного Javascript:

<span>
    <input  ng-model="uploadDownloads" type="file" style="visibility:hidden; width: 1px;" id=uploadDownloads name=uploadDownloads onchange="$(this).parent().find('span').html($(this).val().replace('C:\\fakepath\\', ''))"  /> <!-- Chrome security returns 'C:\fakepath\'  -->
    <input  class="btn btn-primary" type="button" value="choose file" onclick="$(this).parent().find('input[type=file]').click();"/> <!-- on button click fire the file click event -->
    <span  class="badge badge-important" ></span>
</span> 

Функция filereader уже угловая:

$scope.add = function(valid){
        if(valid){
                $scope.data = 'none';
                var f = document.getElementById('uploadDownloads').files[0];
                var r = new FileReader();
                r.onloadend = function(e){
                    $scope.data = e.target.result;
                    $scope.notPass = false;
                    $modalInstance.close({
                        'data':$scope.data,
                        'fileName':$scope.fileName,
                        'fileExplain':$scope.fileExplain
                    });
                };
            /*activate the onloadend to catch the file*/
                r.readAsBinaryString(f);
        } else {
            $scope.notPass = true;
        }
    };

Проблема состоит в том, чтобы активировать onclick и onchange с помощью Angular вместо JavaScript, чтобы my <span> обновлялся с выбранным именем файла.

  • 0
    Какой точный вопрос здесь? Кроме того, ваш код не очень идиоматичен для AngularJS. Вы должны изучить использование ng-change и ng-click. Кроме того, если вы модифицируете DOM, вам следует рассмотреть возможность использования директивы.
  • 0
    я хочу сделать то же самое, что здесь, но с угловым
Показать ещё 11 комментариев
Теги:
filereader

1 ответ

1
Лучший ответ

Этот вопрос основывается на существующем вопросе и ответе. В частности, однако, я изменил код из этого ответа, чтобы разместить то, что, по-видимому, является конкретным вопросом здесь, а именно, как вы обновляете <span> чтобы иметь имя файла, выбранное пользователем, таким образом, что идиоматический для angularjs.

Здесь код с рабочим образцом.

Здесь соответствующая часть html файла:

<body ng-controller="AppController">
    <input ng-model="uploadDownloads" type="file" fd-input file-name="fileName"/> 
    <span class="badge badge-important">Output here: {{fileName}}</span>
</body>

Ключевым здесь является то, что у вас есть настраиваемая директива, называемая fd-input которая имеет двустороннюю привязку к атрибуту, который он определяет, называемому file-name. Вы можете передать одну из ваших переменных $scope в этот атрибут, и директива привяжет к ней имя файла. Здесь контроллер и директива.

(function() {
  'use strict';

  angular.module('app', [])
    .controller('AppController', AppController)
    .directive('fdInput', fdInput);

  function AppController($scope) {
    $scope.fileName = '';
  }

  function fdInput() {
    return {
      scope: {
        fileName: '='
      },
      link: function(scope, element, attrs) {
        element.on('change', function(evt) {
          var files = evt.target.files;
          console.log(files[0].name);
          console.log(files[0].size);

          scope.fileName = files[0].name;
          scope.$apply();
        });
      }
    }
  };

})();

Как упоминалось выше, директива берется непосредственно из другого ответа SO. Я изменил его, чтобы добавить область, которая выполняет двустороннюю привязку к атрибуту file-name:

...
return {
  scope: {
    fileName: '='
  },
...

Затем я назначаю files[0].name для двусторонней привязки:

...
scope.fileName = files[0].name;
scope.$apply();
...

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

Надеюсь, это поможет.

  • 0
    Хорошо, поэтому я добавил его в мой HTML-код и мой угловой контроллер, и это не сработало. но когда я попробовал это в некоторых test.html и test.js, это сработало. я думаю, что это может не сработать, потому что я использую его в angular-ui модале. он загружает файл, но не показывает имя, я думаю, по какой-то причине он не вызывает директиву.
  • 0
    К сожалению, это другой вопрос, который отклоняется от контекста этого вопроса. Я полагаю, что этот ответ решит вашу проблему (если решение работает изолированно), и вы должны продолжить поиск в Stackoverflow, чтобы найти решение для правильного совместного использования вашей области $scope с модальной angular-ui. Ты почти там! :) Если вы не возражаете, отметьте этот ответ, чтобы он не отображался как неотвеченный, когда сообщество ищет ответы на вопросы. Удачи!
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню