создать директиву для входного файла в angularjs

0

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

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

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

<input id="identityDocument" name="identityDocument"
                 ui-jq="filestyle" type="file" class="filestyle input-lg" ui-options="{
                    buttonText: '{{'ACTIONS.UPLOAD' | translate}}',
                    iconName: 'fa fa-inbox'
                  }"
                 accept="image/*">

Я хочу создать переменную для нее, которая вызвала: $scope.candidature.identityDocument

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

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

Еще одна вещь, которую я хочу, - получить требуемую работу над входным файлом, так как нет поддержки type="file" ввода type="file" с помощью службы ng-model.

Я сделал все это, и он работает следующим образом:

это мой html-код для одного ввода:

<div class="row">
        <div class="form-group col-md-4">
          <label for="identityDocument">{{'FME_CANDIDATURE.PERSONAL_INFORMATIONS.IDENTITY_DOCUMENT' |
            translate}}: </label>
          <input id="identityDocument" name="identityDocument"
                 ui-jq="filestyle" type="file" class="filestyle input-lg" ui-options="{
                    buttonText: '{{'ACTIONS.UPLOAD' | translate}}',
                    iconName: 'fa fa-inbox'
                  }"
                 onchange="angular.element(this).scope().setFile(this,'identityDoc')"
                 accept="image/*">
          <p class="help-block" style="color: #ff635d; !important;">
            <span ng-show="step1.identityDocument.$invalid && !step1.identityDocument.$pristine">{{'FME_CANDIDATURE.PERSONAL_INFORMATIONS.IDENTITY_DOCUMENT_ERROR' | translate}}</span>
          </p>
        </div>
        <div class="form-group col-md-4 mb-0">
          <h4 class="custom-font text-greensea"><strong>{{'ACTIONS.PREVIEW' | translate}}</strong></h4>
          <div><img ng-src="{{identityDoc}}" class="md-card-image img-responsive img-thumbnail"
                    alt="{{'ERRORS.NO_PHOTO_SELECTED' | translate}}"></div>

        </div>
      </div>

в этом коде у меня есть входной файл, который принимает только изображения, и когда я выбираю какое-то изображение, я вызываю функцию setFile(), эта функция будет принимать два аргумента, текущий вход и имя, которое я хочу передать в его область (так как ng- модель не работает). и у меня есть еще один div, который будет содержать img для предварительного просмотра выбранного изображения.

И это код функции setFile():

$scope.setFile = function(element, name) {
      $scope.currentFile = element.files[0];
      let reader = new FileReader();

      reader.onload = function(event) {
        //Converts Angular expression into a function, in our case we convert
        //the string we passed as a variable
        //and then assign a value to the parsed string
        $parse(name).assign($scope, event.target.result);
        //the same as above but instead we passing the name of selected image to the candidature object
        $parse('candidature.'+name).assign($scope, element.value.replace(/^.*[\\\/]/, ''));
        $scope.$apply();

      };
      // when the file is read it triggers the onload event above.
      reader.readAsDataURL(element.files[0]);
    };

так что функция принимает входные данные и строку, в этом примере HTML я передаю второй параметр как "identityDocument", эта функция затем создаст переменную с именем: $scope.identityDocument которая будет содержать данные изображения для предварительного просмотра и $scope.candidature.identityDocument который будет содержать имя изображения.

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

app.directive('validFile',function(){
  return {
    require:'ngModel',
    link:function(scope,el,attrs,ngModel){
      //change event is fired when file is selected
      el.bind('change',function(){
        scope.$apply(function(){
          ngModel.$setViewValue(el.val());
          ngModel.$render();
        });
      });
    }
  }
});

следующим образом:

<input ... accept="image/*" valid-file required>

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

Редактировать:

Я добавил эту строку $parse(name+'Upload').assign($scope, element.files[0]); к функции setFile, которую я использую для загрузки файла следующим образом:

let file = $scope.identityDocUpload;
      let fd = new FormData();
      fd.append('file', file);
      $http.post('http://localhost:8080/fileUpload', fd, {
          transformRequest: angular.identity,
          headers: {'Content-Type': undefined}
        })
        .success(function () {
        })
        .error(function () {
        });
  • 0
    Почему вы не используете директивный контроллер?
  • 0
    @TobiasTimm что ты имеешь ввиду?
Показать ещё 2 комментария
Теги:

1 ответ

0

Я бы предложил что-то вроде

(function () {
    'use strict';

    angular
        .module('myApp')
        .directive('validFile', validFile);

    validFile.$inject = [];

    function validFile() {
        var directive = {
        link: link,
        controller: ValidFileController,
        scope: {
                fileRead: '=',
            }
        };
        ValidFileController.$inject = ['$scope'];
        return directive;

        function link(scope, element, attrs, controller) {
            // do UI-things
        }

         function ValidFileController($scope){
            /* jshint validthis: true */
            var vm = this;
            // do controller things
         }
    }

})();

Это директива с контроллером. В этом случае вы можете выполнить всю свою логику в рамках одной директивы и не нуждаться в ng-controller.

Эта ng-model не работает для input type="file" прав, но ваш совершенный код не очень велик, потому что вы получаете доступ к области $scope в html через атрибут html.

Таким образом, ваша техника загрузки может быть заменена

 element.bind('change', function (changeEvent) {
            var reader = new FileReader();
            reader.onload = function (loadEvent) {
               scope.$apply(function () {
                    scope.fileRead = loadEvent.target.result;
                 });
            }
            reader.readAsDataURL(changeEvent.target.files[0]);
        });

Для ваших динамических значений модели вы можете выбирать между различными подходами, fe

$scope['yourAttributeName'] = value;

или

var the_string = 'my.test';
var model = $parse(the_string);
model.assign($scope, 'test');
  • 0
    Окей, спасибо за вашу помощь :)
  • 0
    Обновил ответ

Ещё вопросы

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