在 Angular 自定义表单控件,有时你想要的输入不是标准的文本输入、选择或复选框。经过实现ControlValueAccessor 接口并将组件注册为 NG_VALUE_ACCESSOR,您能够将自定义表单控件无缝地集成到模板驱动或响应表单中,就像它是本地表单同样!git
ControlValueAccessor 是一个接口,充当Angular API 和 DOM 元素之间的桥梁github
export interface ControlValueAccessor { writeValue(obj: any) : void registerOnChange(fn: any) : void registerOnTouched(fn: any) : void }
writeValue(obj:any)是将表单模型中的值写入视图中。ide
writeValue(value: any): void { this._renderer.setProperty(this._elementRef.nativeElement, 'value', value); }
registerOnChange(fn:any)是一个方法,用于注册在视图中的某些内容发生更改时应调用的处理程序。它获取一个函数,告诉其余表单指令和表单控件更新其值。函数
registerOnChange(fn: (_: any) => void): void { this._onChange = fn; }
registerOnTouched(fn:any)与registerOnChange()此相似,它专门为控件接收触摸事件时注册一个处理程序。this
registerOnTouched(fn: any): void { this._onTouched = fn; }
setDisabledState?(isDisabled: boolean): void; 是一个可选的方法,设置自定义表单的状态code
setDisabledState(isDisabled: boolean): void { this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled); }
咱们能够把 ControlValueAccessor 中的方法写在一个抽象类中,不一样的组件能够实现这个基类接口
export abstract class AbstractValueAccessor implements ControlValueAccessor { private _value: any = ''; get value(): any { return this._value; } set value(v: any) { if (v !== this._value) { this._value = v; this.onChange(v); this.onTouched(); } } writeValue(value: any) { this._value = value; } onChange = (_) => {}; onTouched = () => {}; registerOnChange(fn: (_: any) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } } export function MakeProvider(type: any): { provide: any, useExisting: any, multi: boolean} { return { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => type), multi: true }; }
自定义一个 list 控件,能够选择年级事件