Angular.js: поддержка input [type = file] привязка

Созданный на 18 сент. 2012  ·  145Комментарии  ·  Источник: angular/angular.js

привет, пытаюсь выполнить простую загрузку файла :) но ввод type = file, похоже, не связывает ive попробовал hg-model-instant, но ничего не получил, даже обновился до 1.0.2 и ничего

forms moderate not core feature

Самый полезный комментарий

Это решение зависит от реализуемого файлового ридера:

...
.directive('file', function() {
    return {
        restrict: 'E',
        template: '<input type="file" />',
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attr, ctrl) {
            var listener = function() {
                scope.$apply(function() {
                    attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
                });
            }
            element.bind('change', listener);
        }
    }
});

<file name="image" ng-model="inputFile" accept="image/png,image/jpg,image/jpeg" />

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

а если не хватает воображения:

var file = $scope.inputFile;
$http.put('http://localhost:5984/demo/d06917e8d1fae1ae162ea7773c003f0b/' + file.name + '?rev=4-c10029f35a5c5ed9bd8cc31bf8589d3c', file, { headers: { 'Content-Type' : file.type } });

Это работает из-за xhr2 (http://www.html5rocks.com/en/tutorials/file/xhr2), и, пожалуйста, извините за длинный пример URL загрузки, это конечная точка документа couchdb (вложение).

Все 145 Комментарий

Angular не имеет привязки по умолчанию к input type = file.

Но тогда ввод файла возможен только для javascript, единственное преимущество, которое может помочь такая привязка, - это очистить ввод файла. (Я полагаю, что Angular прямо сейчас не поддерживает фреймворк для загрузки файла с помощью ajax)

@coli : это не вся правда.

Имеет смысл иметь возможность перехватывать событие onchange на input [file].

На https://github.com/lgersman/jquery.orangevolt-ampere у нас есть именно такой сценарий: загрузка файлов через XMLHTTPRequest V2.
Поэтому мы реализовали нашу собственную директиву для перехвата событий изменения input [file], чтобы загрузка файлов выполнялась без перезагрузки страницы.

Я бы хотел увидеть эту функцию в angularjs!

Достигнут ли какой-либо прогресс с привязкой к входному файлу типа? Я искал решение и не могу найти того, что работает ...

моим решением был просто Ajax вместо запроса или http.post

отправлено с моего айпада

1 марта 2013 г. в 19:16 "jgoldber" < [email protected] [email protected] > написал:

Достигнут ли какой-либо прогресс с привязкой к входному файлу типа? Я искал решение и не могу его найти.

-
Ответьте на это письмо напрямую или просмотрите его на Gi tHubhttps: //github.com/angular/angular.js/issues/1375#issuecomment -14321221.

Лучшее решение, которое я нашел: http://jsfiddle.net/marcenuc/ADukg/49/. Пожалуйста, поделитесь, если найдете лучшее решение.

Да, на это действительно нужно взглянуть; возможность выбора и загрузки файла очень важна для большинства веб-приложений, поэтому поддержка этого ввода является довольно очевидной отсутствующей функцией.

Удар. Это нужно добавить к вехе.

Еще один крик в поддержку этого.

ng-model может устанавливать значение для файла из HTML5 File API, есть полифиллы Flash и Silverlight для IE8 / IE9

Да, либо установите значение в файл, либо в элемент ввода (содержащий ссылку на файл)

Это решение зависит от реализуемого файлового ридера:

...
.directive('file', function() {
    return {
        restrict: 'E',
        template: '<input type="file" />',
        replace: true,
        require: 'ngModel',
        link: function(scope, element, attr, ctrl) {
            var listener = function() {
                scope.$apply(function() {
                    attr.multiple ? ctrl.$setViewValue(element[0].files) : ctrl.$setViewValue(element[0].files[0]);
                });
            }
            element.bind('change', listener);
        }
    }
});

<file name="image" ng-model="inputFile" accept="image/png,image/jpg,image/jpeg" />

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

а если не хватает воображения:

var file = $scope.inputFile;
$http.put('http://localhost:5984/demo/d06917e8d1fae1ae162ea7773c003f0b/' + file.name + '?rev=4-c10029f35a5c5ed9bd8cc31bf8589d3c', file, { headers: { 'Content-Type' : file.type } });

Это работает из-за xhr2 (http://www.html5rocks.com/en/tutorials/file/xhr2), и, пожалуйста, извините за длинный пример URL загрузки, это конечная точка документа couchdb (вложение).

Это можно сделать в IE8 / 9, объединив этот основанный на флэш-памяти FileReader Polyfill https://github.com/Jahdrien/FileReader и этот чистый полифил js FormData, который полагается на FileReader https://github.com/francois2metz/ html5-formdata. _update_ Moxie - лучший полифилл

Мое решение было довольно схематичным, по крайней мере, таким же схематичным, как и jsfiddle выше, где прототип контроллера натянут ...

В контроллере:

    $scope.updateImage = '(' + function () {
      alert('moo');
    }.toString() + ')();';

Сделайте мой желаемый обратный вызов onchange и оберните его закрытием.

   <input type="file" name="image" onchange="{{updateImage}}" ng-model="image">

Вставьте его в DOM с помощью Angular

Не совсем красиво, но в Webkit работает. Я не проводил кроссбраузерное тестирование.

Я на 1.0.5, но все еще не работает. Мы использовали пример Jgoldber и немного его изменили:
http://jsfiddle.net/ADukg/2589/

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

Еще не тестировал его в IE, но я предполагаю (зная IE), что это не сработает.

Предполагая, что вы просто хотите вызвать функцию в своей области видимости, которая принимает входной элемент в качестве аргумента, это довольно просто реализовать в директиве:

http://jsfiddle.net/neilsarkar/vQzKJ/

(изменено из приведенного выше jsfiddle, спасибо @programmist)

'use strict';

function filesModelDirective(){
  return {
    controller: function($parse, $element, $attrs, $scope){
      var exp = $parse($attrs.filesModel);

      $element.on('change', function(){
        exp.assign($scope, this.files);
        $scope.$apply();
      });
    }
  };
}

конфигурация:

angular.module(...).directive('filesModel', filesModelDirective)

использование:

<input type="file" files-model="someObject.files" multiple>

Пожалуйста, исправьте это в ближайшее время.

По-прежнему возникают проблемы .. в некоторых версиях он работает, но в любом случае не поддерживается

Начиная с версии 1.5.0, если вы используете обходной путь onchange, необходимо вызывать $ digest:

<input type="file" onchange="angular.element(this).scope().myController.uploadFile(this.files[0]); angular.element(this).scope().$digest();">

+1 для лучшей поддержки ng-change и input / file. Пример использования: как загрузчик изображения я хотел бы иметь возможность редактировать это изображение (изменять размер и обрезать) перед загрузкой для оптимального отображения. Реализация: перейдите к изображению (используя input / file), а в событии onchange переместите файл на холст и отредактируйте с помощью fabricjs. Я не могу думать о реализации без изменения.

cztomsik - я использую 1.0.7, и я не могу заставить ваше решение работать - функция scope (this) разрешается нормально, но контроллер не может быть найден, функция uploadFile указана как член области (this).

Кстати, у меня есть небольшая модификация техники, которая, кажется, работает для меня (я до сих пор не знаю, почему у меня были:

<input type = "file" name = "file" ng-model = "file" onchange = "invokeUploadFile (this)" />

var invokeUploadFile = function (that) {
angular.element (это) .scope (). uploadFile (это)
angular.element (это) .scope (). $ digest ();
}

Не могли бы вы предоставить jsfiddle / plunker?
Спасибо


    1. 2013 v 18:17, tb01923 [email protected] :

+1 для лучшей поддержки ng-change и input / file. Пример использования: как загрузчик изображения я хотел бы иметь возможность редактировать это изображение (изменять размер и обрезать) перед загрузкой для оптимального отображения. Реализация: перейдите к изображению (используя input / file), а в событии onchange переместите файл на холст и отредактируйте с помощью fabricjs. Я не могу думать о реализации без изменения.

cztomsik - я использую 1.0.7, и я не могу заставить ваше решение работать - функция scope (this) разрешается нормально, но контроллер не может быть найден, функция uploadFile указана как член объекта scope (this), но когда я удалить контроллер я получаю

Uncaught ReferenceError: uploadFile не определен blah.js: 15
$ scope.upload Файл blah.js: 15
invokeScope blah.js: 4
по изменению

-
Ответьте на это письмо напрямую или просмотрите его на GitHub.

+1. Он нужен для запуска загрузки файла HTML5, когда пользователь выбирает файл. Это легко обойти, но я ожидаю, что это сработает.

+1. пожалуйста, реализуйте, не внедряя это совершенно не интуитивно понятно.

+1

+1

Да ладно, ребята ... Прошло больше года, а angular 1.2.0 по-прежнему не имеет привязок к входным файлам ... Я не понимаю, почему эта функция не добавляется? Было несколько хороших решений для реализации. Я хотел бы получить ответ от члена команды angular по этому поводу, пожалуйста.

Просто чтобы процитировать одно из лучших решений (я знаю, что это односторонняя привязка данных, но все же лучше, чем ничего, проверка и обновление модели работают даже в IE7):

Определение

  /**
   * <strong i="8">@ngdoc</strong> inputType
   * <strong i="9">@name</strong> angular.module.ng.$compileProvider.directive.input.file
   *
   * <strong i="10">@description</strong>
   * HTML file input field.
   *
   * <strong i="11">@param</strong> {string} ngModel Assignable angular expression to data-bind to.
   * <strong i="12">@param</strong> {string} multiple Allows multiple files selection.
   * <strong i="13">@param</strong> {string=} name Property name of the form under which the 
                                control is published.
   *
   * <strong i="14">@example</strong>
      <doc:example>
        <doc:source>
         <script>
           function Ctrl($scope) {
           }
         </script>
         <form name="myForm" ng-controller="Ctrl">
           file: <input type="file" ng-model="file"> single file selection.<br/>
           files: <input type="file" ng-model="files" multiple> multi-file selection.<br/>
           <tt>file.name = {{file.name}}</tt><br/>
           <tt>files.length = {{files.length}}</tt><br/>
          </form>
        </doc:source>
        <doc:scenario>
          it('should change state', function() {
            expect(binding('file.name')).toBeUndefined();

            input('file').select('a file name');
            expect(binding('file.name')).toEqual('a file name');
          });
        </doc:scenario>
      </doc:example>
   */
  'file': fileInputType,

Функция

function fileInputType(scope, element, attr, ctrl) {
  element.bind('change', function() {
    scope.$apply(function() {
      var files = element[0].files,
          isValid = true;

      if (msie < 10) {
        files = [element[0].value];
      }

      if (attr.accept) {
        var i, j, acceptType, fileType,
            types = map(attr.accept.split(','), function(t) { return trim(t).split('/'); });
        for (i = 0; i < files.length && isValid; ++i) {
          fileType = files[i].type.split('/');
          isValid = false;
          for (j = 0; j < types.length && !isValid; ++j) {
            acceptType = types[j];
            isValid = acceptType[0] === fileType[0] && (acceptType[1] === '*' || acceptType[1] === fileType[1]);
          }
        }
      }
      ctrl.$setValidity('file', isValid);

      var viewValue;
      if (isValid) viewValue = attr.multiple ? files : files[0];
      ctrl.$setViewValue(viewValue);
    });
  });
}

+1

+1

@ntrp Почему ты не

Это изменение нужно немного проработать и протестировать, у меня сейчас нет на это времени.

+1

+1

-1: троллфейс:

Шучу +1

+1

+1

+1

+1

+1

input [type = file] на самом деле не является двухсторонним связыванием, если мы явно не используем File API, который доступен не во всех целевых браузерах. Добавление этого к ng-модели не имеет большого смысла, но есть множество плагинов, поддерживающих некоторые варианты этой функциональности. Разве мы не можем просто делегировать это на время плагинам?

http://caniuse.com/fileapi

@caitp Верно, но имеет смысл иметь возможность привязаться к событию изменения через ng-change, что не работает.

Еще одна вещь, которая не работает, - это проверка формы. Я думаю, что поддержка файлов должна быть реализована для новых браузеров с резервным вариантом односторонней привязки данных для старых. Если это решение нежизнеспособно, то, на мой взгляд, в вики следует четко указать, почему эта функция не реализована и как решить проблемы, вызванные отсутствием поддержки. Я помню, как потерял много времени, прежде чем решить свои потребности в входных файлах, когда я их впервые использовал.

Дело в том, что имена файлов не привязаны к модели, и на самом деле не имеет смысла привязывать их к модели. Каждое свойство интерфейса File доступно только для чтения, а интерфейс FileList представляет собой только набор файлов. Нет возможности для двухстороннего связывания, поэтому нет реальной причины использовать ng-model для них в первую очередь. Достаточно просто вместо этого привязаться к событию change , и вы можете легко написать директиву для добавления этой функции, чтобы вы могли использовать ее декларативно, если она вам нужна.

Но какой смысл сделать это частью ng-модели, если у нее нет возможности следовать поведению ng-модели?

Нет причин, по которым нельзя создать пользовательский интерфейс для файлов, и angular может в какой-то момент сделать это, но, на мой взгляд, это не имеет смысла с ng-model. Я не знаю, что думают об этом другие разработчики, могут они согласиться, а могут и нет. Но, с моей точки зрения, отдельная директива имела бы больше смысла, потому что input [type = file] просто не вписывается в ng-модель

  • Ничего о значении входного файла нельзя записать из контекста скрипта.
  • У нас нет реального способа выполнить проверку без File API (который не поддерживается в нескольких целевых браузерах), браузер, по сути, делает это за нас. --- за исключением проверки ngRequired

Единственное, что мы действительно могли сделать для input [type = file], это $ setViewValue, когда значение изменяется (что на самом деле не имеет смысла), и каким-то образом изменить ngModel, чтобы игнорировать изменения значения модели, вызванные изменением скрипта (или в основном просто отключите $ watch полностью). Что касается проверки, все, что мы действительно можем поддерживать, - это ng-required, я имею в виду, что еще мы можем там сделать?

Я также хотел бы иметь возможность поддерживать ввод файла с помощью ngModel, но я не вижу, как это будет работать, это просто не вписывается в интерфейс ngModel.

Я согласен с этим утверждением, но, как я уже сказал ранее, нам нужно больше внимания уделять этому в вики или в целом в документации, чтобы разработчики знали, что им нужно делать, чтобы достичь нужной им функциональности.

@ntrp ну патчи документации более чем приветствуются, и я буду рад просмотреть их, если вы их отправите :)

Может ли добавление конкретной директивы в angular быть решением?

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

Ах, хорошо, @caitp , некоторое время назад я читал, что вики-запрос на вытягивание на самом деле не подвергался активной оценке, поэтому я не удосужился внести свой вклад. Если у меня скоро появится свободное время, я с радостью внесу свой вклад :) Спасибо.

Я не понимал, что директива ngChange также требует наличия ngModel, и я думаю, поэтому здесь так много обсуждается ngModel (и именно поэтому я получаю эту ошибку ). Я согласен с тем, что двусторонняя привязка к входу [type = file] не имеет смысла.

Но какова точная причина того, что ngModel требуется ngChange? На мой взгляд, имеет смысл иметь возможность привязаться к событию изменения поля input [type = file], скажем, если вы хотите автоматически отправлять форму после выбора файла. В таком случае мне все равно, каково значение поля. Меня волнует только то, что это изменилось. Лучший способ, который я нашел для решения такой проблемы, - это обходной путь, упомянутый выше @cztomsik :

onchange="angular.element(this).scope().fileChangedHandler()"

И это действительно не лучшее решение.

ng-change , несмотря на то, что назван аналогично другим директивам обработчика событий, на самом деле не является обработчиком для события change . Он просто добавляет $viewChangeListener к ngModelController, который запускается всякий раз, когда вызывается $setViewValue .

Я согласен, это неудачное имя

Это обман # 1236, который был закрыт этим комментарием: https://github.com/angular/angular.js/issues/1236#issuecomment -29115377

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

+1

@IgorMinar взгляните сюда, немного грязный, но очень интересный пример реализации: https://github.com/danialfarid/angular-file-upload. @danialfarid добивается больших успехов в этом.

Проверьте, как это проблема для всех, несколько вопросов открылись с несколькими комментариями. Вы должны предоставить нам модуль ngUpload: smile :. Возможно, вы можете предоставить реализацию html5 и добавить примеры использования с https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills#file -api в http://docs.angularjs.org/guide / т.е.

Как вы думаете решить?

+1

+1

+1

+1

+1

+1

+1

+1

Вау, на данном этапе это немного неловко.

+1

На самом деле невозможно иметь двусторонние привязки для ввода файлов, особенно когда целевые браузеры не все поддерживают File API (http://caniuse.com/fileapi) --- Но даже когда они могут, input[type=file] в любом случае не вписывается в это. 2-сторонняя привязка там действительно невозможна

Извините, но это скорее проблема / функция безопасности веб-платформы, чем что-либо еще. Если бы это было возможно, это было бы сделано

@caitp Я полностью понимаю, что вы говорите, но «это больше проблема / функция безопасности веб-платформы, чем что-либо еще» - это немного нелепое заявление. Фреймворки предназначены для устранения недостатков браузеров, веб-спецификаций и различных несоответствий. Это, безусловно, одно из тех мест, где предостережение в отношении fileAPI является адекватным. Теперь есть решения, почему бы не сложить их?

Для этого, например, что-нибудь простое, например обертка, могло бы стать началом.

Учитывая направление, в котором движется Angular 2.0 (перенос идиом только angular, не-ECMA), я не думаю, что ограничения «веб-платформы» должны вызывать беспокойство.

@everyone else: Что делает Эмбер в этом случае?

Изменить: удаление «требуется» из оператора транспилирования.

_Просто быстрое разъяснение. _ Для создания приложений Angular 2.0 не требуется транслируемый язык или идиомы, отличные от ECMA. Вы можете использовать простой код ES5. Если вы хотите собрать исходный код Angular 2.0, вам нужно использовать traceur для компиляции. Естественно, вы можете использовать traceur для создания своих собственных приложений и воспользоваться теми же функциями, которые мы используем внутри Angular, но это совершенно необязательно. Извините, если в наших объявлениях была некоторая путаница по этому поводу.

@EisenbergEffect Мое плохое. Я знал это, и мне следовало лучше вычитать. Никакого кофе!

Фреймворки не могут обойти ограничения веб-платформы. Например, мы не можем заставить браузер разрешить нам писать в атрибуты IDL только для чтения (что действительно нарушает двустороннюю привязку файлов), и мы не можем заставить браузер открывать нам файловую систему, что действительно мешает нам делать что-нибудь интересное с этим

@caitp Я

Возможно, мы сможем переориентировать этот разговор на вопрос: «Как angular может это поддержать?» вместо «Это не впишется в наши текущие шаблоны».

Привязка к вводу файла определенно возможна, на самом деле я делал это в предыдущем проекте для AngularJS.

Тот факт, что вы не можете выполнять двустороннюю привязку с вводом файлов, является функцией безопасности, и это имеет смысл. Авторы никогда не смогут установить путь к файлу через скрипт, но почему бы просто не связать его в одну сторону?

Конечно, это нарушает парадигму, но кого это волнует, означает ли это, что вы получаете ng-изменение и возможность доступа к файлам через файловый API без взлома? jQuery может привязываться к событию изменения на входных данных файла, настолько ли священный способ Angular, что мы не можем просто привязать его к контроллеру? Техническое ограничение в архитектуре или просто идеологический барьер?

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

20 мая 2014 года в 7:53 Джастин Арруда < [email protected] [email protected] > написал:

@c aitph https: //github.com/caitp Я

Возможно, мы сможем переориентировать этот разговор на вопрос: «Как angular может это поддержать?» вместо «Это не впишется в наши текущие шаблоны».

-
Ответьте на это письмо напрямую или просмотрите его на Gi tHubhttps: //github.com/angular/angular.js/issues/1375#issuecomment -43636326.

Тогда у вас есть один случай, когда ng-model ведет себя совершенно по-разному для одного конкретного элемента управления формы, а затем у вас есть люди, регистрирующие ошибки, такие как «почему элемент управления формы отправляет неправильный файл, когда я меняю значение на« foobarblah.txt »или что-то еще. Несогласованный API -> плохо.

ngModel не совсем идеален для этого, особенно потому, что это означает, что у нас есть определенный шаблон, в который можно вписаться, и авторам приложений очень сложно отключить его. Однако есть решения для этого в angular.dart и прототипе v2.0.0, так что в будущем это будет лучше. Но мы действительно не можем добавить другое поведение ng-model, которое игнорирует все, что делает ng-model в настоящее время, это не имеет смысла.

принимает файл и загружает его через XHR, используя Angular

@guruward, мы не можем поддерживать это во всех наших целевых браузерах для 1.x, не заставляя людей использовать полифиллы ударной волны или аналогичные. Существуют сторонние модули, которые позволяют это сделать, и их можно использовать вместо них. angular-file-upload одновременно поставляет нативные версии shockwave polyfill и html5 и выбирает правильную. Так что это неплохое решение, настоятельно рекомендуется, если вы хотите это сделать.

Но я не уверен, что это что-то, что мы можем вставить в ядро, вы должны спросить Игоря, что он думает о поставке ударно-волнового полифила в ядре.

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

Что плохого в использовании для этого сторонних модулей?

Этот полифилл не требует вспышки.

@jreading - это не полифилл, и раньше он поставлялся с флэш-загрузчиком, он, вероятно, где-то еще есть.

Он полагается на File API, который доступен не во всех целевых браузерах и поэтому проблематичен для ядра angular 1.x.

Без этого API у вас нет возможности добраться до файлового блоба без чего-то вроде ударной волны.

Он использует iframe вместо flash, вы можете подумать об этом . Вместо того, чтобы спорить о семантике, как насчет дорожной карты? Начнем с ng-change при вводе файла для браузеров, поддерживающих файловый API.

@jreading, к сожалению, не помогает браузерам, которые не поддерживают API, в том числе IE9, который все еще поддерживается. Мы не можем предоставить API, который работает в поддерживаемом браузере A, но не поддерживает браузер B в ядре, без какой-либо работы для людей, которые зависят от поддержки IE9. И нет, iframe не раскрывает содержимое файла как большой двоичный объект и не делает его загружаемым. Hnnggggg.

Для этого есть решения в сторонних модулях, которые приложения могут использовать, если сочтут их подходящими. Помещение этого в ядро ​​A) затрудняет работу этих сторонних модулей, а B) не поддерживает все целевые браузеры, поэтому это проблема.

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

Какой вред от использования сторонних модулей, если они работают на вас, а они вам нужны?

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

Сторонние модули - это единственный способ или агрессивные улучшения, такие как мой пост в блоге (вам не нужно загружать !!), но я мог бы просто перевернуть вопрос и спросить: "Что плохого в том, чтобы иметь лучший API для современных браузеров?"

"Что плохого в том, чтобы иметь лучший API для современных браузеров?"

Этот аргумент слаб, потому что он не принимает во внимание альтернативные издержки; у нас (основной команды) есть много других вещей, над которыми нужно поработать.

Справедливо. По ощущениям просто огромная щель и низко висящий фрукт.

Проблема здесь не в том, как заставить это работать с ngModel. Я думаю, что ngModel может выставить FileList из поля ввода в область видимости, но в другом направлении мы разрешили бы только установку модели на null / undefined для поддержки. парсеры / средства форматирования, скорее всего, ничего не будут делать, а валидаторы будут просто делать простые вещи, например, проверять наличие или отсутствие файла.

Проблема в том (как упоминалось ранее) в том, что без поддержки файлового api это невозможно сделать для ядра, учитывая, что наша базовая линия - IE9, и о полифилдинге этого материала для ядра не может быть и речи.

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

неосновные решения, которые справляются с этим, уже существуют, и они были упомянуты в этом обсуждении проблемы, а также в предыдущем выпуске

Есть много других вещей, которые имеют большее влияние, и мы хотим их выполнить. Я понимаю, что это относительно частый случай, но до сих пор не слышал, почему существующих решений недостаточно?

Можно ли перенаправить часть энергии, вложенной в это обсуждение, на улучшение существующих решений, если они в этом нуждаются, или на создание нового решения, превосходящего существующие?

Я собираюсь закрыть это так же, как мы закрыли # 1236. Angular 2 создается для поддержки современных браузеров, и с этим файловая поддержка будет легко доступна.

Я просто хочу знать, когда происходит событие изменения, чтобы я мог напрямую получить доступ к элементу, получить информацию о файле и загрузить через AJAJ.

@bjoshuanoah, тогда зачем тебе ngModel? Просто привяжите прослушиватель событий к input = p

@caitp Я хочу контролировать все в контроллере, а не с помощью директивы.

Если я поставлю ng-change = "uploadFile ({$ event: $ event})"

У меня может быть $ scope.uploadFile (event) в моем контроллере. и обработайте это там.

Мой конкретный вариант использования таков: загрузите файл в s3, примените URL-адрес к моей модели.

вместо этого я должен проникнуть в прицел, чтобы сделать то же самое. Очень назойливый:

<input name="highRes" scope="{{contentOptions.currentValue}}" key="value" type="file" onchange="angular.element(this).scope().setFile(this)">

Я хочу, чтобы кто-то убил эту проблему. так что мы все можем двигаться дальше :)

25 июля 2014 г. в 9:22 Брайан < [email protected] [email protected] > написал:

Я просто хочу знать, когда происходит событие изменения, чтобы я мог напрямую получить доступ к элементу, получить информацию о файле и загрузить через AJAJ.

-
Ответьте на это письмо напрямую или просмотрите его на Gi tHubhttps: //github.com/angular/angular.js/issues/1375#issuecomment -50171714.

+1

+1

+1000000000000000

+1

+1

+1

+1

+100500

+1
Я не уверен, почему проблема с Ajax. Можно загрузить данные из файла csv на локальном компьютере в модель Angular. Если бы ng-change работал с вводом файлов в Angular, это было бы легко, в настоящее время это не так . Этот сценарий вообще не требует Ajax или серверного API. Я тоже не уверен, почему это закрыто?

Мой текущий обходной путь - сделать следующее

 input(type="file", onchange="angular.element(this).scope().onFileSet(this.files)")

и в моем контроллере есть что-то вроде

$scope.onFileSet = function(files) { 
// work your magic here 
}

Вряд ли, я чувствую, что использую angular как инструмент. Мы будем очень признательны за любое понимание того, как сделать это более угловатым способом.

: сердце:: сердце:

Вот парусник:: парусник:

@samccone Разве scope () не недоступен, когда режим отладки выключен?

@geetsce Это правильно (в 1.3.x и новее)

добро пожаловать, в 1.2 земле все хорошо.

@Narretz, у тебя есть лучшее решение?

Это работает для меня, это вдохновлено https://jasonturim.wordpress.com/2013/09/01/angularjs-drag-and-drop

<input type="file" multiple="multiple" data-dbinf-on-files-selected="chooseAFunctionName(selectedFileList)">
<script>
/**Directive to propagate selected files from an HTML input element with type="file"
 * to the surrounding AngularJS controller.
 */
myApp.directive('dbinfOnFilesSelected', [function() {
    return {
        restrict: 'A',
        scope: {
              //attribute data-dbinf-on-files-selected (normalized to dbinfOnFilesSelected) identifies the action
              //to take when file(s) are selected. The '&' says to  execute the expression for attribute
              //data-dbinf-on-files-selected in the context of the parent scope. Note though that this '&'
              //concerns visibility of the properties and functions of the parent scope, it does not
              //fire the parent scope's $digest (dirty checking): use $scope.$apply() to update views
              //(calling scope.$apply() here in the directive had no visible effect for me).
            dbinfOnFilesSelected: '&'
        },
        link: function(scope, element, attr, ctrl) {
            element.bind("change", function()
            {  //match the selected files to the name 'selectedFileList', and
               //execute the code in the data-dbinf-on-files-selected attribute
             scope.dbinfOnFilesSelected({selectedFileList : element[0].files});
            });
        }
    }
}]);

myApp.controller('myController', ['$scope', function($scope) {
    $scope.chooseAFunctionName = function (filelist) {
        for (var i = 0; i < filelist.length; ++i) {
            var file = filelist.item(i);
            //do something with file; remember to call $scope.$apply() to trigger $digest (dirty checking)
            alert(file.name);
           }
    };
}]);
</script>

+1

+1

Этого не будет ... Отпусти, отпусти ...

+1

Как сказал @samccone ,

input(type="file", onchange="angular.element(this).scope().onFileSet(this.files)")

Это не подход Angular. Это странно.

+1

+1

+1

привет @caitp @Narretz, если вы, ребята, хотели бы, чтобы я мог разработать PR для этого для ветки 1.2x, дайте мне знать, хотите ли вы это добавить или нет. Я понимаю проблемы безопасности и отсутствие кроссбраузерной поддержки в том, что касается получения доступа к фактическому файловому объекту, однако похоже, что базовая поддержка для обнаружения изменения ввода файла (передача исходного события) обеспечит достаточную ловушку чтобы люди творили свою магию.

Еще раз спасибо за все, что вы делаете: palm_tree:

+1

+1

+1

+1

+1

ng-file-upload отлично работает.

+1 за @neokyol !! Он отлично работает!

эта общая функция должна быть по умолчанию в framework

полезный

+1

+1

+1

+1

+1

это сработало для меня, может помочь

angular.module('app', [])
  .controller('MainCtrl', MainCtrl)
  .directive('fileChange', fileChange);

  function MainCtrl($scope) {
    $scope.upload = function () {
      // do something with the file
      alert($scope.file.name);
    };
  }

  function fileChange() {
    return {
      restrict: 'A',
      require: 'ngModel',
      scope: {
        fileChange: '&'
      },
      link: function link(scope, element, attrs, ctrl) {
        element.on('change', onChange);

        scope.$on('destroy', function () {
          element.off('change', onChange);
        });

        function onChange() {
          ctrl.$setViewValue(element[0].files[0]);
          scope.fileChange();
        }
      }
    };
  }
<div ng-app="app" ng-controller="MainCtrl">
  <input type="file" file-change="upload()" ng-model="file">
</div>

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

+1

+1

+1

+1

+1000000000000000000000000

+1

+1

@dciccale , пожалуйста, приведите пример плункера.

+1

+1

+1 Для этого в базовую библиотеку должна быть встроена директива. Это довольно смешно

+1

+1
запланирована ли эта функция для одного из следующих выпусков?

+1

+1

Как это сделать в проектах, где $ scope никогда не вводится в контроллер. Я использую laravel angular, который использует способ объявления контроллеров GULP и ES6.

т.е.

class TestController{
    constructor(API){
        'ngInject';
        this.API = API
    }

    $onInit(){
        this.file = null;
    }
    upload() {
        console.log(this.file)
    }
    fileChanged(elm) {
        console.log('hey')
        this.file = elm.file;
        this.$apply();
    }
}

export const TestComponent = {
    templateUrl: './views/app/components/test/test.component.html',
    controller: TestController,
    controllerAs: 'vm',
    bindings: {}
}

Я считаю, что нашел работу. http://stackoverflow.com/questions/38449126/how-to-set-up-ng-file-upload-in-laravel-angular-project/38486379#38486379

+1

@ntrp @guruward @coli @lgersman @jgoldber @Siyfion
Как вы исправили валидацию для
Моя проверка:
this.catalougeForm = this.catalougeFormBuilder.group ({
catalougeIconName: ['', Validators.required]
});
HTML:
(изменение) = "changeListener ($ event)">

Мой валидатор считает значение catalougeIconName пустым / нулевым после загрузки.
Изображение отправляется, но валидатор не работает

Есть обновления по этому поводу?

Любые обновления ?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги