【发布时间】:2021-04-22 14:52:48
【问题描述】:
我有一个带有自定义 FormControl 的响应式表单。第一次加载屏幕,虽然自定义控件是必填字段,但我的Form是有效的。
如果我触发了任何更改,例如通过勾选表单中的复选框,那么在我向自定义控件填充值之前,表单将被标记为无效。
如果我重置自定义控件的值,则表单会再次被标记为无效,并且从那时起它会按预期工作。
所以只有当表单第一次在屏幕上加载时才会出现问题。
我在控制台中注意到以下异常:
这个错误是由我的自定义控件的验证器触发的,因为如果我评论它,错误就会消失。
下面是我的自定义控件的代码。我是不是做错了什么?
import { Component, forwardRef, Input, OnInit, Output } from '@angular/core';
import { ControlValueAccessor, FormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-multiple-checkbox',
templateUrl: './multiple-checkbox.component.html',
styleUrls: ['./multiple-checkbox.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MultipleCheckboxComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => MultipleCheckboxComponent),
multi: true
}]
})
export class MultipleCheckboxComponent implements OnInit, ControlValueAccessor {
value = [];
disabled = false;
@Input() public options: { key, value }[];
onTouched: any;
onChange: any;
constructor() { }
validate({ value }: FormControl) {
const isNotValid = this.value.length === 0;
return isNotValid && {
invalid: true
};
}
ngOnInit(): void { }
evaluate(event, key): void {
if (event.target.checked) {
this.value.push(key);
} else {
this.value.splice(this.value.findIndex(i => key === i), 1);
}
this.onChange(this.value);
this.onTouched();
}
isChecked(key): boolean {
return this.value.findIndex(e => e === key) > -1;
}
writeValue(value: any): void {
this.value = value;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
this.disabled = isDisabled;
}
}
[编辑] 添加自定义控件在其父窗体中添加到屏幕的方式:
<div [formGroup]="form">
<div *ngIf="control.visible">
<div [ngSwitch]="control.controlType">
<div *ngSwitchCase="'checkbox'">
<label [attr.for]="control.key">{{control.label}}</label>
<input [formControlName]="control.key" [id]="control.key" type="checkbox"
(change)="evaluate(control.key)">
</div>
<!-- THIS IS MY CUSTOM CONTROL -->
<app-multiple-checkbox *ngSwitchCase="'multipleCheckbox'" [formControlName]="control.key"
[options]="control.options" (change)="evaluate(control.key)">
</app-multiple-checkbox>
</div>
</div>
[编辑]
根据下面的评论,错误是由我表单中的这一行触发的:
<button type="submit" color="accent" (click)="save()"
[disabled]="catalogForm.invalid">Submit</button>
【问题讨论】:
-
你能创建 stackblitz 吗?
-
您能否展示一下您是如何使用此自定义组件的,例如你如何将它嵌入到你的模板中?
validate方法是如何被调用的?您是否将其用作使用此组件的FormControl的ValidatorFn? -
@Eddi 我编辑了缺少信息的问题。我刚刚实现了
Validator接口,所以不需要做任何其他调用。同样,除了第一次(在表单变脏之前)之外,工作正常 -
@Sam 这对我来说看起来不错。您提供的错误消息说明了第 11 行
catalog.component.html中的[disabled]属性。所以基本上您在那里使用的任何表达式都“过早地”改变了。在大多数情况下,我知道当您更改ngAfterViewInit中的表达式值时会发生这种情况。 -
实际上对于响应式表单更常见的方式是订阅 ts 文件中表单的
valueChanges而不是模板(change)处理程序。我相信它可以解决您的问题
标签: angular angular-reactive-forms