在Angular中,可以通过实现ControlValueAccessor接口来创建自定义表单控件。要使表单控件永远不会使表单变脏,可以在自定义控件中禁用ngModel的dirty属性。
以下是一个示例,展示了如何创建一个自定义的input控件,其值始终为脏值,而不会影响整个表单的脏状态:
import { Directive, ElementRef, forwardRef, HostListener, Renderer2 } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Directive({
selector: 'input[customControl]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomControlDirective),
multi: true
}
]
})
export class CustomControlDirective implements ControlValueAccessor {
private _value: any = '';
// 注入依赖项
constructor(private renderer: Renderer2, private elementRef: ElementRef) {}
// 设置控件值
set value(value: any) {
if (this._value !== value) {
this._value = value;
this.onChange(value);
}
}
// 获取控件值
get value(): any {
return this._value;
}
// 在控件值发生变化时调用该方法
onChange: any = () => {};
// 在控件被触碰(touched)时调用该方法
onTouched: any = () => {};
// 用于注册回调函数的方法
registerOnChange(fn: any): void {
this.onChange = fn;
}
// 用于注册回调函数的方法
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
// 写入控件值的方法
writeValue(value: any): void {
this.value = value;
this.renderer.setProperty(this.elementRef.nativeElement, 'value', value);
}
// 监听控件的input事件
@HostListener('input', ['$event.target.value'])
onInput(value: any): void {
this.value = value;
}
}
在上述示例中,当自定义控件的值发生变化时,通过调用onChange
方法来通知Angular表单控件的值已经变化。但是,我们并没有修改表单的状态,因此它永远不会被设置为脏状态。