programing

각도 재료를 사용한 파일 업로드

fastcode 2023. 3. 21. 22:37
반응형

각도 재료를 사용한 파일 업로드

나는 Angular로 웹 앱을 만들고 있다.JS 및 각질 재료.문제는 각질 재료에 파일 입력을 위한 내장 구성 요소가 없다는 것입니다.(파일 업로드가 소재 디자인에 맞지 않는 것 같습니다만, 앱에 필요합니다.)

이 문제에 대한 좋은 해결책이 있나요?

레오카세이로의 멋진 솔루션

<input class="ng-hide" id="input-file-id" multiple type="file" />
<label for="input-file-id" class="md-button md-raised md-primary">Choose Files</label>

여기에 이미지 설명 입력

코드펜으로 표시

Angular 6+의 경우:

HTML:

<input #csvInput hidden="true" type="file" onclick="this.value=null" (change)="csvInputChange($event)" accept=".csv"/>
<button mat-flat-button color="primary" (click)="csvInput.click()">Choose Spreadsheet File (CSV)</button>

컴포넌트 방법:

  csvInputChange(fileInputEvent: any) {
    console.log(fileInputEvent.target.files[0]);
  }

주의: 이 필터는 다음 필터만 허용하도록 합니다..csv파일을 표시합니다.

솔루션의 또 다른 예입니다.다음과 같이 됩니다.

CodePen 링크입니다.

  <choose-file layout="row">
    <input id="fileInput" type="file" class="ng-hide">
    <md-input-container flex class="md-block">
      <input type="text" ng-model="fileName" disabled>
      <div class="hint">Select your file</div>
    </md-input-container>
    <div>
      <md-button id="uploadButton" class="md-fab md-mini">
        <md-icon class="material-icons">attach_file</md-icon>
      </md-button>
    </div>
  </choose-file>   

.directive('chooseFile', function() {
    return {
      link: function (scope, elem, attrs) {
        var button = elem.find('button');
        var input = angular.element(elem[0].querySelector('input#fileInput'));

        button.bind('click', function() {
          input[0].click();
        });

        input.bind('change', function(e) {
          scope.$apply(function() {
            var files = e.target.files;
            if (files[0]) {
              scope.fileName = files[0].name;
            } else {
              scope.fileName = null;
            }
          });
        });
      }
    };
  });

도움이 됐으면 좋겠다!

이 답변에 근거해서.이 어프로치를 실시하는데 시간이 걸렸기 때문에, 제 회답이 누군가의 시간을 절약해 주었으면 합니다.

CodePen 데모

지시:

angular.module('app').directive('apsUploadFile', apsUploadFile);

function apsUploadFile() {
    var directive = {
        restrict: 'E',
        templateUrl: 'upload.file.template.html',
        link: apsUploadFileLink
    };
    return directive;
}

function apsUploadFileLink(scope, element, attrs) {
    var input = $(element[0].querySelector('#fileInput'));
    var button = $(element[0].querySelector('#uploadButton'));
    var textInput = $(element[0].querySelector('#textInput'));

    if (input.length && button.length && textInput.length) {
        button.click(function (e) {
            input.click();
        });
        textInput.click(function (e) {
            input.click();
        });
    }

    input.on('change', function (e) {
        var files = e.target.files;
        if (files[0]) {
            scope.fileName = files[0].name;
        } else {
            scope.fileName = null;
        }
        scope.$apply();
    });
}

upload.file.filename.filename.dev

<input id="fileInput" type="file" class="ng-hide">
<md-button id="uploadButton"
           class="md-raised md-primary"
           aria-label="attach_file">
    Choose file
</md-button>
<md-input-container md-no-float>
    <input id="textInput" ng-model="fileName" type="text" placeholder="No file chosen" ng-readonly="true">
</md-input-container>

from jameswyse(https://github.com/angular/material/issues/3310에서)

HTML

<input id="fileInput" name="file" type="file" class="ng-hide" multiple>
<md-button id="uploadButton" class="md-raised md-primary"> Choose Files </md-button>

제어 장치

    var link = function (scope, element, attrs) {
    const input = element.find('#fileInput');
    const button = element.find('#uploadButton');

    if (input.length && button.length) {
        button.click((e) => input.click());
    }
}

나한테는 통했어

각진 재료 포함
HTML

<div (click)="uploadFile.click()">
   <button mat-raised-button color="primary">Choose File</button>
   <input #uploadFile (change)="upload($event)" type='file' style="display:none"/> 
</div>

ts

upload(event:Event){
   console.log(event)
}

스택 점멸

여기 게재된 정보와 각진 재료에 대한 컴포넌트 맞춤 가능성에 대해 설명했습니다.이것은 외부 libs와 선택된 파일의 이름을 필드로 피드백하지 않고 공헌한 것입니다.

여기에 이미지 설명 입력

여기에 이미지 설명 입력

HTML

<mat-form-field class="columns">
    <mat-label *ngIf="selectedFiles; else newFile">{{selectedFiles.item(0).name}}</mat-label>
    <ng-template #newFile>
        <mat-label>Choose file</mat-label>
    </ng-template>
    <input matInput disabled>
    <button mat-icon-button matSuffix (click)="fileInput.click()">
        <mat-icon>attach_file</mat-icon>
    </button>
    <input hidden (change)="selectFile($event)" #fileInput type="file" id="file">
</mat-form-field>

TS

selectFile(event) {
    this.selectedFiles = event.target.files;
}

나만의 파일 선택 버튼 스타일링을 피할 수 있는 방법을 찾았습니다.

다시 업로드 할 때 flowjs를 사용하기 때문에 ng-flowflow-btn 디렉티브를 사용할 수 있습니다.이것은 재료 디자인 스타일의 파일 선택 버튼을 제공합니다.

입력 요소를 md-button 안쪽으로 감아도 동작하지 않습니다.

입력 내용을 레이블 안으로 줄 바꿈으로써 스타일을 변경하고 입력 표시를 없음으로 변경할 수 있습니다.그런 다음 스팬 요소 내에 표시할 문자를 지정할 수 있습니다.주의: 여기서는 부트스트랩4 버튼 스타일(btn btn-outline-primary)을 사용했습니다.원하는 스타일을 사용하실 수 있습니다.

<label class="btn btn-outline-primary">
      <span>Select File</span>
      <input type="file">
</label>

input {
  display: none;
}
html:
    <div class="upload">
        <span>upload image</span>
        <input
          #Image
          type="file"
          (change)="handleFileInput($event.target.files)"
          accept=".jpg,.svg,.png,.jpeg"
        />
        <img
          width="100%"
          height="100%"
          *ngIf="imageUrl"
          [src]="imageUrl"
          class="image"
        />
    </div>

app.component.ts

export class AppComponent {
  options = [{ value: "This is value 1", checked: true }];
  statuses = ["control"];

  // name = "Angular";//
  fileToUpload: any;
  imageUrl: any;
  handleFileInput(file: FileList) {
    this.fileToUpload = file.item(0);

    //Show image preview
    let reader = new FileReader();
    reader.onload = (event: any) => {
      this.imageUrl = event.target.result;
    };
    reader.readAsDataURL(this.fileToUpload);
  }
}

Proxy 버튼을 구현하면 좀 더 깔끔해질 수 있지만, 또 다른 해킹 솔루션은 다음과 같습니다.

HTML:

<input id="fileInput" type="file">
<md-button class="md-raised" ng-click="upload()">
  <label>AwesomeButtonName</label>
</md-button>

JS:

app.controller('NiceCtrl', function ( $scope) {
  $scope.upload = function () {
    angular.element(document.querySelector('#fileInput')).click();
  };
};

위의 모든 답변에 덧붙여(그래서 커뮤니티 Wiki로 만들었습니다), 아마 다음 중 하나를 마크하는 것이 가장 좋습니다.input<type="text">와 함께tabindex="-1"(특히 디세이블이 아닌 읽기 전용을 사용하는 경우)<input type="file">숨겨야 하지만 아직 문서 안에 있는 것 같습니다).탭/입력 키 조합 사용 시 라벨이 올바르게 동작하지 않았지만 버튼은 동작했습니다.따라서 이 페이지의 다른 솔루션 중 하나를 복사하는 경우 이러한 내용을 변경할 수 있습니다.

AngularJs Material 및 MIME 유형 유효성 검사를 사용하는 파일 업로더:

지시:

function apsUploadFile() {
    var directive = {
        restrict: 'E',
        require:['ngModel', 'apsUploadFile'],
        transclude: true,
        scope: {
            label: '@',
            mimeType: '@',
        },
        templateUrl: '/build/html/aps-file-upload.html',
        controllerAs: 'ctrl',
        controller: function($scope) {
            var self = this;

            this.model = null;

            this.setModel = function(ngModel) {
                this.$error = ngModel.$error;

                ngModel.$render = function() {
                    self.model = ngModel.$viewValue;
                };

                $scope.$watch('ctrl.model', function(newval) {
                    ngModel.$setViewValue(newval);
                });
            };
        },
        link: apsUploadFileLink
    };
    return directive;
}

function apsUploadFileLink(scope, element, attrs, controllers) {

    var ngModelCtrl = controllers[0];
    var apsUploadFile = controllers[1];

    apsUploadFile.inputname = attrs.name;
    apsUploadFile.setModel(ngModelCtrl);

    var reg;
    attrs.$observe('mimeType', function(value) {
        var accept = value.replace(/,/g,'|');
        reg = new RegExp(accept, "i");
        ngModelCtrl.$validate();
    });

    ngModelCtrl.$validators.mimetype = function(modelValue, viewValue) {

        if(modelValue.data == null){
            return apsUploadFile.valid = true;
        }

        if(modelValue.type.match(reg)){
            return apsUploadFile.valid = true;
        }else{
            return apsUploadFile.valid = false;
        }

    };

    var input = $(element[0].querySelector('#fileInput'));
    var button = $(element[0].querySelector('#uploadButton'));
    var textInput = $(element[0].querySelector('#textInput'));

    if (input.length && button.length && textInput.length) {
        button.click(function(e) {
            input.click();
        });
        textInput.click(function(e) {
            input.click();
        });
    }

    input.on('change', function(e) {

        //scope.fileLoaded(e);
        var files = e.target.files;

        if (files[0]) {
            ngModelCtrl.$viewValue.filename = scope.filename = files[0].name;
            ngModelCtrl.$viewValue.type = files[0].type;
            ngModelCtrl.$viewValue.size = files[0].size;

            var fileReader = new FileReader();
            fileReader.onload = function () {
                ngModelCtrl.$viewValue.data = fileReader.result;
                ngModelCtrl.$validate();
            };
            fileReader.readAsDataURL(files[0]);

            ngModelCtrl.$render();
        } else {
            ngModelCtrl.$viewValue = null;
        }

        scope.$apply();
    });

}
app.directive('apsUploadFile', apsUploadFile);

html 템플릿:

<input id="fileInput" type="file" name="ctrl.inputname" class="ng-hide">
<md-input-container md-is-error="!ctrl.valid">
    <label>{@{label}@}</label>
    <input id="textInput" ng-model="ctrl.model.filename" type="text" ng-readonly="true">
    <div ng-messages="ctrl.$error" ng-transclude></div>
</md-input-container>
<md-button id="uploadButton" class="md-icon-button md-primary" aria-label="attach_file">
    <md-icon class="material-icons">cloud_upload</md-icon>
</md-button>

예:

<div layout-gt-sm="row">
    <aps-upload-file name="strip" ng-model="cardDesign.strip" label="Strip" mime-type="image/png" class="md-block">
        <div ng-message="mimetype" class="md-input-message-animation ng-scope" style="opacity: 1; margin-top: 0px;">Your image must be PNG.</div>
    </aps-upload-file>
</div>

언급URL : https://stackoverflow.com/questions/31867194/file-upload-with-angular-material

반응형