簡體   English   中英

將 DOM 事件傳遞給 Angular 中的自定義表單驗證器

[英]Pass a DOM event to custom form validator in Angular

我正在嘗試使用反應式方法驗證表單。 我正在使用文件輸入從用戶那里獲取文件。 我定義了一個自定義驗證器,允許用戶在特定條件下上傳文件。 嘗試這樣做時,出現錯誤。 驗證器不會接收整個事件,而只會接收文件的路徑,例如C:\fakepath\abc.xlsx 我想傳遞 DOM 事件,以便我可以處理文件的所有屬性,如類型、大小等。

這是我的代碼:

文件.驗證器.ts

import { AbstractControl } from '@angular/forms';

export function ValidateFile(control: AbstractControl) : 
{ [key: string]: boolean } | null {
    const value = control.value;

    if (!value) {
        return null;
    }

    return value.length < 0 && value.files[0].type !== '.xlsx' && value.files[0].size > 5000000
    ? { invalidFile: true } : null;

}

工作表.component.ts

constructor(
private formBuilder: FormBuilder,
private alertService: AlertService
) {
    this.sheetForm = this.formBuilder.group({
    sheetType: ['Select Sheet Type', [Validators.required]],
    sheetUpload: [null, [Validators.required, ValidateFile]],
    sheetDescription: [
      null,
      [
        Validators.required,
        Validators.minLength(10),
        Validators.maxLength(100),
      ],
    ],
  });
}

工作表.component.html

<div class="input-group">
    <label for="sheet-upload">Upload Sheet: </label> &nbsp; &nbsp;
    <input
      id="sheet-upload"
      type="file"
      (change)="handleFileInput($event)"
      formControlName="sheetUpload"
      accept=".xlsx"
    />
    <small
      id="custom-error-message"
      *ngIf="
        (sheetForm.get('sheetUpload').dirty ||
          sheetForm.get('sheetUpload').touched) &&
        sheetForm.get('sheetUpload').invalid
      "
    >
      The file size exceeds 5 MB or isn't a valid excel type. Please
      upload again.
    </small>
</div>

任何幫助,將不勝感激。 謝謝!

不確定這是否是最好的方法,但它有效

  • 創建指令以將本機元素附加到表單控件
  • 驗證時從驗證器中的本機元素獲取文件
  • 並且要使用 formControlName,您需要在父元素中分配一個 formGroup(如果包含在其他父元素中則忽略)
@Directive({
  selector: '[formControlName]',
})
export class NativeElementInjectorDirective implements OnInit {
  constructor(private el: ElementRef, private control: NgControl) {}

  ngOnInit() {
    (this.control.control as any).nativeElement = this.el.nativeElement;
  }
}

文件.驗證器.ts

export function ValidateFile(control: any): { [key: string]: boolean } | null {
  const value = control.value;
  const file = control?.nativeElement?.files[0];

  if (!value) {
    return null;
  }

  return value.length < 0 || file.type !== 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.size > 5000000
    ? { invalidFile: true }
    : null;
}

工作表.component.html

<div class="input-group" [formGroup]="sheetForm">
  <label for="sheet-upload">Upload Sheet: </label> &nbsp; &nbsp;
  <input
    id="sheet-upload"
    type="file"
    formControlName="sheetUpload"
    accept=".xlsx"
  />
  <small
    id="custom-error-message"
    *ngIf="
      (sheetForm.get('sheetUpload').dirty ||
        sheetForm.get('sheetUpload').touched) &&
      sheetForm.get('sheetUpload').invalid
    "
  >
    The file size exceeds 5 MB or isn't a valid excel type. Please upload again.
  </small>
</div>

您可以獲得對輸入元素的引用並在驗證器中使用它。

<input #sheetUpload ...>

@ViewChild('sheetUpload') fileInput: HTMLInputElement;

private ValidateFile(): ValidatorFn {
return (control) => {
  const value = control.value;

  if (!value || !this.fileInput) {
    return null;
  }

  const file = this.fileInput.files[0];

  return value.length < 0 && file.type !== '.xlsx' && file.size > 5000000
    ? { invalidFile: file.name }
    : null;
  }
}

暫無
暫無

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

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