簡體   English   中英

如何自定義輸入類型文件圖像的驗證

[英]how to customize the validation of input type file image

你好,我想驗證一個輸入文件 html 類型的圖像,只接受“ png', 'jpg', 'jpeg', 'gif ”,並且不大於 2mb,直到我可以使它成為可能只是它不帶我this.firstFormGroup.controls.image .status如果您輸入任何其他文件被激活為有效狀態。

 handleFileInput(event) {

  const file = event.target.files[0];
  const typeFile = file.type.split('/');
  const filemb: number = file.size / 1000000;
  if (filemb <= 2 && (typeFile[1] === 'png' || typeFile[1] === 'jpg' || typeFile[1] === 'jpeg' || typeFile[1] === 'gif') ) {
        const filePath = `${this.rutaImg}/${file.name}`;
        const fileRef = this.storage.ref(filePath);
        const task = this.storage.upload(filePath, file);
        this.uploadPercent = task.percentageChanges();
        task.snapshotChanges().pipe(
            finalize(() => {
              this.downloadURL = fileRef.getDownloadURL();
              this.downloadURL.subscribe( url => {
                if ( url ) {
                  this.urlImg = url;
                  console.log(this.urlImg);
                  this.validateImage = true;
                  console.log(this.validateImage );
                  return {
                    isError: this.validateImage
                };
                }
             });
            })
         )
        .subscribe();

  } else {
    this.validateImage = false;
  }
}

html代碼

    <div>
        <input formControlName="image"  (change)="handleFileInput($event)" type="file"  id="file" class="inputfile" accept="image/*"  required/>
        <label for="file"><mdb-icon icon="camera"></mdb-icon> Insertar Imagen &nbsp;
          <progress  style="margin-top: -10px; " *ngIf="uploadPercent" max="100" [value]="(uploadPercent | async)"></progress>
       </label>
 </div>

表單組

this.firstFormGroup = this.fb.group({
      ruc: ['', rucValidator],
      razon_social: ['', nameValidator],
      nameBussines: ['', nameValidator],
      phone: ['', phoneValidator],
      describe: ['', describeValidator],
      plan: ['', Validators.required],
      category: ['', Validators.required],
      image: ['', this.validateImage]
    });

您必須創建一個自定義 FormControl,我將向您展示如何創建它( 在線示例)或者您可以使用 npm 模塊( FileInputAccessor


創建FormControl並上傳有效文件的步驟

  1. 實現 ControlValueAccessor
  2. 添加自定義驗證規則
    • 注冊自定義驗證規則
  3. 在你的反應形式中聆聽變化事件
    • 將有效文件上傳到您的存儲空間

1.實現ControlValueAccessor

image-formcontrol.component

 import { Component, OnInit, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ImageFormcontrol } from './image-formcontrol'; @Component({ selector: 'app-image-formcontrol', templateUrl: './image-formcontrol.component.html', styleUrls: ['./image-formcontrol.component.css'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ImageFormcontrolComponent), multi: true } ] }) export class ImageFormcontrolComponent implements OnInit, ControlValueAccessor { _registerOnChangeFn; _registerOnTouchedFn; constructor() { } ngOnInit() { } handleFileInput(event: Event) { const file = (event.target as HTMLInputElement).files[0]; this.writeValue({ file }); } writeValue(value: ImageFormcontrol.Value) { if (this._registerOnTouchedFn) { this._registerOnTouchedFn(); } if (this._registerOnChangeFn) { // update value and validity this._registerOnChangeFn(value); } } registerOnChange(fn) { this._registerOnChangeFn = fn; } registerOnTouched(fn) { this._registerOnTouchedFn = fn; } }
 <input (change)="handleFileInput($event)" type="file" id="file" class="inputfile" accept="image/*" />


2.新增自定義驗證規則

圖像表單控件驗證器

 export function allowedTypes(pattern: string[]): ValidatorFn { return (control: AbstractControl): { [key: string]: any } | null => { const value = control.value as ImageFormcontrol.Value; const valid = null; const isUndefined = !value || !value.file; if (isUndefined) { return valid; } const allowed = new RegExp(`(${pattern.join('|')})`, 'ig').test(value.file.type); if (allowed) { return valid; } else { const invalid = { 'allowedTypes': { value: control.value } }; return invalid; } }; }

——

2-1.注冊自定義驗證規則

app.component(您可以將其更改為您的組件,僅用於演示目的)

 export class AppComponent { firstFormGroup: FormGroup; constructor(private fb: FormBuilder) { } ngOnInit() { const imageFormControl = new FormControl('', ImageFormcontrolValidator.allowedTypes(['jpeg'])); this.firstFormGroup = this.fb.group({ image: imageFormControl }); } }


3. 在你的反應形式中聆聽變化事件

  • 將有效文件上傳到您的存儲空間

 export class AppComponent { firstFormGroup: FormGroup; constructor(private fb: FormBuilder) { } ngOnInit() { const imageFormControl = new FormControl('', ImageFormcontrolValidator.allowedTypes(['jpeg'])); this.firstFormGroup = this.fb.group({ image: imageFormControl }); imageFormControl.statusChanges.subscribe((status) => { switch (status) { case 'VALID': // Upload the valid file to your storage const value = imageFormControl.value as ImageFormcontrol.Value; this.upload(value.file); break; } }); } private upload(file: File) { console.log('upload', file); /* your custom logic const filePath = `${this.rutaImg}/${file.name}`; const fileRef = this.storage.ref(filePath); const task = this.storage.upload(filePath, file); this.uploadPercent = task.percentageChanges(); task.snapshotChanges().pipe( finalize(() => { this.downloadURL = fileRef.getDownloadURL(); this.downloadURL.subscribe( url => { if ( url ) { this.urlImg = url; console.log(this.urlImg); this.validateImage = true; console.log(this.validateImage ); return { isError: this.validateImage }; } }); }) ) .subscribe(); */ } }

我有一個可以幫助你或幫助任何人的 stackblitz。 並不完美,但經過大量閱讀和研究。 我僅將其用於驗證文件擴展名。

https://angular-fileupload-custom-validator-reactive-form.stackblitz.io

我在這里繼續:

  1. 為您的 FormGroup 或 Form Builder 創建自定義驗證器。

  2. 將它添加到您的組件並定義允許的擴展文件數組。

  3. 將無效或有效狀態返回到您的輸入表單。

輸入文件類型所需文件的自定義驗證

requiredFileType.ts

import { AbstractControl, FormControl } from "@angular/forms";
export function requiredFileType(type: string[]) {
  return function(control: FormControl) {
    // return (control: AbstractControl): { [key: string]: any } | null => {
    const file = control.value;
    const valid = null;
    if (file) {
      // console.log(file);
      var path = file.replace(/^.*[\\\/]/, "");
      //   var el_down = path
      //     .split("\\")
      //     .pop()
      //     .split("/")
      //     .pop();

      const extension = path.split(".")[1].toUpperCase();
      console.log(extension + "extension" + type.length);
      var existValue: boolean = false;
      for (var i = 0; i < type.length; i++) {
        let typeFile = type[i].toUpperCase();
        if (typeFile === extension.toUpperCase()) {
          console.log("type" + typeFile);
          existValue = true;
        }
      }
      if (existValue == true) {
        return null;
      } else {
        return {
          requiredFileType: true
        };
      }
      return null;
    }
    return null;
  };
}

組件.ts

 this.addSlot
        .get("FileUpload")
        .setValidators([
          Validators.required,
          requiredFileType(["jpg", "png", "txt"])
        ]);

html

<div class="col-sm-5">
          <input
            type="file"
            formControlName="FileUpload"
            [class.is-invalid]="FileUpload.invalid && uploadPanel"
            class="form-control"
            (click)="handleFileInput($event.target.files)"
            #inputTypeFile
          />

          <!-- <button onclick="document.getElementById('abc').click()">
            choose file
          </button> -->
          <div *ngIf="FileUpload.invalid && uploadPanel">
            <small *ngIf="FileUpload.errors?.required" class="text-danger"
              >File is required</small
            >
            <small
              *ngIf="FileUpload.errors?.requiredFileType"
              class="text-danger"
              >File is required</small
            >
          </div>
        </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM