簡體   English   中英

Angular2:驗證 <input type=“file”/> 更改要上載的文件時不會觸發

[英]Angular2: validation for <input type=“file”/> won't trigger when changing the file to upload

當文件輸入發生變化時,Angular 2似乎在運行驗證時遇到麻煩。

我做了一個插圖來說明這個問題:

我創建了一個formGroup

this.frm = new FormGroup({
    file: new FormControl("", this.validateFile)
});

在validateFile函數中,我拋出一個警報並記錄到控制台:

public validateFile(formControl: FormControl): {[key: string]: any; } {
   alert('Validation ran');
   console.log('Validation ran');
}

Plunkr來說明問題: https ://plnkr.co/edit/Pgcg4IkejgaH5YgbY3Ar?p = preview

驗證將在初始化頁面時運行,但每次更改要上載的文件時都不會運行。

有沒有解決這個問題的方法?

我用kemsky答案和塞巴斯蒂安的評論修正了它。 我創建了一個ngValueAccessor,它在每個帶有類型文件的輸入上注冊自己。

Plunkr可以在這里找到。

最相關的代碼+解釋如下:

這為文件輸入添加了一個ControlValueAccessor,有一天它可能是角度框架本身的一部分( #7341 )。 文件輸入與其他控件的工作方式不同。 這段代碼確保將所選文件作為值讀取:

import {Directive} from "@angular/core";
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from "@angular/forms";

@Directive({
    selector: "input[type=file]",
    host : {
        "(change)" : "onChange($event.target.files)",
        "(blur)": "onTouched()"
    },
    providers: [
        { provide: NG_VALUE_ACCESSOR, useExisting: FileValueAccessor, multi: true }
    ]
})
export class FileValueAccessor implements ControlValueAccessor {
    value: any;
    onChange = (_) => {};
    onTouched = () => {};

    writeValue(value) {}
    registerOnChange(fn: any) { this.onChange = fn; }
    registerOnTouched(fn: any) { this.onTouched = fn; }
}

對於'required'驗證,我創建了一個驗證器,我通過將靜態驗證方法添加到文件FormControl for ReactiveForms來使用。 (或作為模板驅動形式的指令)。

import {Directive} from "@angular/core";
import {NG_VALIDATORS, Validator, FormControl} from "@angular/forms";

@Directive({
    selector: "[requiredFile]",
    providers: [
        { provide: NG_VALIDATORS, useExisting: FileValidator, multi: true },
    ]
})
export class FileValidator implements Validator {
    static validate(c: FormControl): {[key: string]: any} {
        return c.value == null || c.value.length == 0 ? { "required" : true} : null;
    }

    validate(c: FormControl): {[key: string]: any} {
        return FileValidator.validate(c);
    }
}

構建我的表單如下所示:

private buildForm() {
    this.frm = new FormGroup({
        file: new FormControl("",    [FileValidator.validate])
    });
}

而對於HTML:

<input type="file" formControlName="file"/>

Angular 4+改變了主機綁定。

import { Directive, HostListener } from "@angular/core";
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";

@Directive({
    selector: "input[type=file]",
    providers: [
        {provide: NG_VALUE_ACCESSOR, useExisting: FileValueAccessorDirective, multi: true}
    ]
})
export class FileValueAccessorDirective implements ControlValueAccessor {
    @HostListener('change', ['$event.target.files']) onChange = (_) => {};
    @HostListener('blur') onTouched = () => {};

    writeValue(value) {}
    registerOnChange(fn: any) { this.onChange = fn; }
    registerOnTouched(fn: any) { this.onTouched = fn; }
}

目前不支持使用類型file輸入,請參閱#7341

暫無
暫無

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

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