在Angular中传递一个DOM事件给自定义表单验证器



我正在尝试使用响应式方法验证表单。我正在使用文件输入从用户获取文件。我定义了一个自定义验证器,允许用户在特定条件下上传文件。而试图这样做,我得到一个错误。验证器不接收整个事件,而只接收文件的路径,比如C:fakepathabc.xlsx。我想传递DOM事件,这样我就可以处理文件的所有属性,如类型,大小等。

下面是我的代码:

file.validator.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;
}

sheet.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),
],
],
});
}

sheet.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(忽略包含在其他父元素中的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;
}
}

file.validator.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;
}

sheet.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;
}
}

最新更新