Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.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
Javascript 自定义表单控件(ControlValueAccessor)的绑定模型总是将表单设置为脏状态_Javascript_Angular_Typescript - Fatal编程技术网

Javascript 自定义表单控件(ControlValueAccessor)的绑定模型总是将表单设置为脏状态

Javascript 自定义表单控件(ControlValueAccessor)的绑定模型总是将表单设置为脏状态,javascript,angular,typescript,Javascript,Angular,Typescript,我正在尝试实现一个非常简单的自定义表单控件 @Component({ selector: 'text-input', template: '<input [(ngModel)]="value" />', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextInputComponent), multi: tru

我正在尝试实现一个非常简单的自定义表单控件

@Component({
    selector: 'text-input',
    template: '<input [(ngModel)]="value" />',
    providers: [{
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => TextInputComponent),
        multi: true
    }]
})
export class TextInputComponent implements ControlValueAccessor {
    private _value: any;

    get value(): any { return this._value; }
    set value(value: any) { return this.writeValue(value); }

    writeValue(value: any) {
        if (value !== this._value) {
            this._value = value;
            this.onChange(value);
        }
    }

    onChange = (x: any) => { };
    onTouched = () => { };
    registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
    registerOnTouched(fn: () => void): void { this.onTouched = fn; }
}
我的实现有什么问题吗?如何使自定义控件在发生交互时
dirty
仅设置为true的方式下工作


Plunkr复制:

编辑:经过进一步的修补,我终于找到了我认为应该是正确的实现

我简直不敢相信,我从来没有在网上找到一个好的解释,说明
onChange
writeValue
函数如何对应脏/预存状态,以及如何处理重置

只要调用
onChange
,控件就会设置为
dirty:true
。调用
form.reset()
将重置此状态,但也调用
writeValue
设置新值。因此,决不在此方法中调用
onChange
,因为它会破坏您的状态

在我的实现中,我为我的值设置了一个简单的setter,在其中我调用
onChange
来实际设置正确的状态,因为setter仅由模板中的输入控件调用

您的控件可能对值的实际更改方式有更复杂的处理,但只要您真正调用
onChange
,如果您想将更改反映到外部,并且您可以使用
writeValue
设置控件的值,而不更改状态,一切都会正常工作

@Component({
    selector: 'text-input',
    template: `<input [(ngModel)]="value"
                  (blur)="onTouched()" />`,
    providers: [{
        provide: NG_VALUE_ACCESSOR,
        useExisting: forwardRef(() => TextInputComponent),
        multi: true
    }]
})
export class TextInputComponent implements ControlValueAccessor {
    private _value: any;

    // NOTE: you could also just bind to a normal field without
    // getters and setters and call onChange from your template
    // e.g. from (ngModelChange) of the input control
    get value(): any { return this._value; }
    set value(value: any) {
        this.writeValue(value);
        this.onChange(value);
    }

    writeValue(value: any) {
        if (value !== this._value) {
            this._value = value;
        }
    }

    onChange(x: any) { console.log(x); }
    onTouch() { };
    registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
    registerOnTouched(fn: () => void): void { this.onTouched = fn; }
}
@组件({
选择器:“文本输入”,
模板:``,
供应商:[{
提供:NG_值访问器,
useExisting:forwardRef(()=>TextInputComponent),
多:真的
}]
})
导出类TextInputComponent实现ControlValueAccessor{
私有_值:任何;
//注意:您也可以只绑定到一个普通字段,而不需要
//getter和setter,并从模板中调用onChange
//例如,来自输入控件的(ngModelChange)
get value():任何{返回此值。_value;}
设置值(值:任意){
此.writeValue(值);
这个。onChange(值);
}
writeValue(值:任意){
如果(值!==此值){
此值为._值=值;
}
}
onChange(x:any){console.log(x);}
onTouch(){};
registerChange(fn:(:any)=>void):void{this.onChange=fn;}
registerOnTouched(fn:()=>void):void{this.onTouched=fn;}
}