在Angular中使用自定义指令上传多个文件

时间:2019-08-13 11:26:52

标签: angular file-upload angular-reactive-forms directive custom-directive

我正在尝试创建一个自定义指令以验证多个文件的上传。但是在自定义指令中,控件只是返回最后一个文件的详细信息,而不是返回数组。

下面是代码:

File-upload.html:

<form [formGroup]="validateDocumentForm">
<input formControlName="document"  style="display: none" type="file" multiple (change)="onFileChanged($event)" #fileInput accept="application/pdf"  class="form-control">
<button class="btn upload-doc-btn" (click)="fileInput.click()"><span><i class="material-icons">vertical_align_top</i> Upload File</span></button>

file-upload.ts

ngOnInit() {
this.validateDocumentForm = this.formBuilder.group({
  document: this.formBuilder.array(['', [
    CustomValidator.uploadDocument
  ]]),
});

}

Custom-validator.ts:

export class CustomValidator {
    static uploadDocument(control: AbstractControl): 
    ValidationErrors | null {
      console.log(control); // only last file's details instead of 
                               array of selected files.
      console.log(control.value);
      return  null;
   }
}

2 个答案:

答案 0 :(得分:1)

关于这个问题,您是否可以在单独的文件中实现CustomValidator,我找到了本教程: https://dev.to/angular/implement-file-upload-with-firebase-storage-in-our-angular-app-the-simple-way-1ofi

基本上,您正在将一个方法作为验证器绑定到保存表单的组件中,这将在验证文件中调用一个单独的方法。

我希望这个较晚的答案可以对某人有所帮助。

答案 1 :(得分:0)

实际上,您不应使用formArray进行文件上传。如果使用formArray,则需要在html文件的循环中进行迭代。(FormArray

ngOnInit() {
    this.validateDocumentForm = this.formBuilder.group({
        'document':[''] 
    })
})

选定的文件将不会在value中使用,而是必须使用目标中的files

onFileChanged(event) {
    for (const x of event.target.files) {
        console.log(x);
        // do the validation here
    }
}

尝试在组件文件中而不是在custom.validator文件中进行验证

编辑

我们必须将文件存储在formcontrol中,以便您可以在组件文件中执行类似的操作

ngOnInit() {
    this.validateDocumentForm = this.formBuilder.group({
        'document':['', uploadDocument] 
    })
})

onFileChanged(event) {
    this.validateDocumentForm['controls']['document']['files'] = event.target.files;
}

和custom.validators文件中的

export function uploadDocument(c: AbstractControl) {
    console.log(c);
if (c['target'] && 'files' in c['target']) {
    for (const x of c['target'].files) {
        if (/*do your condition*/) {
            return {
                'fileNotValid': true
            };
        }
    }
 }
    return null;
}