Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度2:验证<;输入类型=";文件"/&燃气轮机;韩元';更改要上载的文件时不会触发_Angular_Angular2 Forms - Fatal编程技术网

Angular 角度2:验证<;输入类型=";文件"/&燃气轮机;韩元';更改要上载的文件时不会触发

Angular 角度2:验证<;输入类型=";文件"/&燃气轮机;韩元';更改要上载的文件时不会触发,angular,angular2-forms,Angular,Angular2 Forms,Angular 2似乎在文件输入更改时运行验证时遇到问题 为了说明这个问题,我做了一个简单的说明: 我组成了一个像 this.frm = new FormGroup({ file: new FormControl("", this.validateFile) }); 在validateFile函数中,我向控制台抛出警报和日志: public validateFile(formControl: FormControl): {[key: string]: any; } { alert

Angular 2似乎在文件输入更改时运行验证时遇到问题

为了说明这个问题,我做了一个简单的说明:

我组成了一个像

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解释了这个问题:

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


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

当前不支持使用
文件类型输入,请参见我使用kemsky答案和Sebastien的评论修复了它。
我制作了一个ngValueAccessor,它用类型file在每个输入上注册自己

可以找到Plunkr

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

这为文件输入添加了ControlValueAccessor,该文件输入可能是angular framework本身的一部分()。 文件输入的工作方式与其他控件不同。这段代码确保所选文件被读取为值:

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; }
}
对于“必需”验证,我制作了一个验证器,通过将静态验证方法添加到反应表单的文件FormControl中来使用它。(或作为模板驱动表单的指令)

构建我的表单如下所示:

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

它不受支持,但您可以让它工作。在链接的讨论中,有一个如何做的例子。嗨,谢谢你的帮助。我试着在angular 4.3上运行它,但它不起作用。首先,在我上传文件后,它仍然无效,在提交后,它只是一个空字符串。。我需要换点什么?再次感谢,@S.Robijns我没有plunker要展示,只是什么都没发生。在onSubmit()函数中获取文件对象是否成功?Thx.@S.Robijns这在Angular 5+中不起作用,这里是一个示例,它似乎在Angular 4中没有变化,看起来HostBinding en HostListener一直存在。这两种方法都有效,但根据样式指南,这一种确实是首选()刚刚遇到一个案例,证明使用主机绑定肯定更好,因为它们可以被继承,而当您将其放入decorator时则不能。更多信息:我可能会修改我的答案later@MrBoJangles是的,idd。。不要再指望它了,时间是至关重要的,我的朋友:)@Fritz这在Angular 5+中不起作用,这里是一个例子
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; }
}