我有一个关于重置带有自定义输入的表单的问题。
我将验证消息绑定到输入的 Touched 属性。 在默认输入上,form.reset() 还将触摸状态重置回 false,在自定义输入上,它不会转发。
我添加了一个plunkr https://plnkr.co/edit/ZyELDDFf3rxQRipHlWnb?p=preview来说明问题:触摸并离开两个控件,两个控件都被触摸:true,然后重置。 我如何将这个清除重置事件(将触摸状态恢复为 false)转发到我的自定义输入?
@Component({
selector: 'my-app',
template: `
<p><span class="boldspan">Form data:</span>{{demoForm.value | json}}</p>
<p><span class="boldspan">Model data:</span> {{dataModel}}</p>
<form #demoForm="ngForm">
<custom-input name="someValue" [(ngModel)]="dataModel">
custom input
</custom-input>
<label>native input<br>
<input type="text" [(ngModel)]="someOtherValue" name="someOtherValue"
#sOV="ngModel"></label>
<div>touched: {{sOV.touched}}</div>
</form>
<br>
<button (click)="demoForm.reset()">Reset Form</button>`
})
export class App {
dataModel: string = '';
}
谢谢并致以诚挚的问候
这是我迄今为止使用的解决方案:
@Component({
selector: 'custom-input',
standalone: true,
imports: [CommonModule, FormsModule],
template: `<div class="form-group">
<label><ng-content></ng-content>
<input [(ngModel)]="value"
class="form-control"
(blur)="onBlur()"
#i="ngModel">
</label>
<div>touched: (custom-input) {{i.touched}}</div>
</div>`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomInputComponent),
multi: true,
},
],
})
export class CustomInputComponent implements ControlValueAccessor, OnInit {
private innerValue: any = '';
private onTouchedCallback: () => void = () => null;
private onChangeCallback: (_: any) => void = () => null;
// 1 add injector
constructor(private injector: Injector) {}
// 2 prepare field to access ngcontrol of the custom-input.component and ngcontrol of the input in the template
private model?: NgControl;
@ViewChild('i') input?: NgControl;
ngOnInit() {
// 3 get ngcontrol of the custom-input.component
this.model = this.injector.get(NgControl);
if (this.model) {
// 4 subscribe to custom-input ngcontrol's statusChange to sync both ngcontrols
this.model.statusChanges?.subscribe(() => {
if (!this.input || !this.model) return;
if (this.model.touched !== this.input.touched)
this.model.touched
? this.input.control?.markAsTouched()
: this.input.control?.markAsUntouched();
});
}
}
get value(): any {
return this.innerValue;
}
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
onBlur() {
this.onTouchedCallback();
}
writeValue(value: any) {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
}
这里是演示:https://stackblitz.com/edit/stackblitz-starters-yu8tda?file=src%2Fcustom-input.component.ts
使用
demoForm.resetForm()
而不是
demoForm.reset()