Angular2:验证 <input type="file"/>更改要上传的文件时不会触发 [英] Angular2: validation for <input type="file"/> won't trigger when changing the file to upload

查看:32
本文介绍了Angular2:验证 <input type="file"/>更改要上传的文件时不会触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当文件输入更改时,Angular 2 似乎无法运行验证.

Angular 2 seems to have troubles with running validation when a file input changes.

我做了一个 plunk 来说明这个问题:

I made a plunk to illustrate this problem:

我制作了一个表单组

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

在 validateFile 函数中,我抛出一个警报并登录到控制台:

And in the validateFile function I throw an alert and log to the console:

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

Plunkr 来说明这个问题:https://plnkr.co/edit/Pgcg4IkejgaH5YgbY3Ar?p=预览

Plunkr to illustrate the issue: https://plnkr.co/edit/Pgcg4IkejgaH5YgbY3Ar?p=preview

验证将在初始化页面时运行,但不会在每次更改要上传的文件时运行.

The validation will run when initializing the page but won't run each time you change the file to be uploaded.

有什么办法可以解决这个问题吗?

Is there any solution to this problem?

推荐答案

我使用 kemsky answer 和 Sebastien 的评论修复了它.我制作了一个 ngValueAccessor,它在每个输入上使用类型文件注册自己.

I fixed it using kemsky answer and Sebastien's comment. I made a ngValueAccessor which registers itself on every input with type file.

可以在此处找到Plunkr.

Plunkr can be found here.

最相关的代码+下面的解释:

Most relevant code + explanation beneath:

这为文件输入添加了一个 ControlValueAccessor,它可能有一天成为 angular 框架本身的一部分(#7341).文件输入的工作方式与其他控件不同.这段代码确保所选文件被读取为值:

This adds a ControlValueAccessor for file inputs which might be part of the angular framework itself someday(#7341). A file input works different than other controls. This piece of code makes sure the selected files are read as the value:

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

对于必需"验证,我制作了一个验证器,我通过将静态验证方法添加到 ReactiveForms 的文件 FormControl 来使用它.(或作为模板驱动表单的指令).

And for the 'required' validation I made a validator which I use by adding the static validate method to the file FormControl for ReactiveForms. (or as a directive for template driven forms).

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);
    }
}

构建我的表单如下所示:

Building my form looks like this:

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

对于 html:

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

这篇关于Angular2:验证 &lt;input type="file"/&gt;更改要上传的文件时不会触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆