我已经通过模板驱动的表单实现了一个自定义表单控件,它将输入包装在html中并添加了一个标签等。它与ngModel上的2way数据绑定很好地对话。问题是,表单在初始化时会自动标记为脏。有没有办法防止这种情况发生,所以我可以在表单上使用这些属性,它们将是准确的?
自定义选择器(除了自动标记为脏之外,此功能正常):
<form class="custom-wrapper" #searchForm="ngForm">
{{searchForm.dirty}}
{{test}}
<custom-input name="testing" id="test" label="Hello" [(ngModel)]="test"></custom-input>
<pre>{{ searchForm.value | json }}</pre>
</form>
自定义输入模板:
<div class="custom-wrapper col-xs-12">
<div class="row input-row">
<div class="col-xs-3 col-md-4 no-padding" *ngIf="!NoLabel">
<label [innerText]="label" class="inputLabel"></label>
</div>
<div class="col-xs-9 col-md-8 no-padding">
<input pInput name="cust-input" [(ngModel)]="value" />
</div>
</div>
</div>
自定义输入组件:
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
import { Component, Input, forwardRef } from "@angular/core";
@Component({
selector: "custom-input",
template: require("./custom-input.component.html"),
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => QdxInputComponent),
multi: true
}
]
})
export class CustomInputComponent implements ControlValueAccessor {
@Input("value") _value = "";
get value() {
return this._value;
}
set value(val: string) {
this._value = val;
this.propagateChange(val);
}
@Input() noLabel: boolean = false;
@Input() label: string = "Label required";
propagateChange = (_: any) => {};
writeValue(value) {
if (value !== undefined) {
this.value = value;
}
}
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn) {}
}
答案 0 :(得分:4)
我只用一个属性指令解决了这个问题:
import { Directive } from '@angular/core';
import { NgControl } from '@angular/forms';
@Directive({
selector: '[ignoreDirty]'
})
export class IgnoreDirtyDirective {
constructor(private control: NgControl) {
this.control.valueChanges.subscribe(v => {
if (this.control.dirty) {
this.control.control.markAsPristine();
}
});
}
}
您可以通过以下方式在代码中使用它:
<input ignoreDirty type="text" name="my-name" [(ngModel)]="myData">
答案 1 :(得分:2)
您传播的更改就是标记为脏的原因。只需调整您的/app
函数不传播更改,因为逻辑上它不应该创建更改:
writeValue
很快:在export class CustomInputComponent implements ControlValueAccessor {
@Input("value") _value = "";
get value() {
return this._value;
}
set value(val: string) {
this._value = val;
this.propagateChange(val);
}
@Input() noLabel: boolean = false;
@Input() label: string = "Label required";
propagateChange = (_: any) => {};
writeValue(value) {
if (value !== undefined) {
this._value = value;
}
}
registerOnChange(fn) {
this.propagateChange = fn;
}
registerOnTouched(fn) {}
}
this._value
代替this.value