Angular 使用 ControlValueAccessor 建立自定義表單控件

在 Angular 自定義表單控件,有時你想要的輸入不是標準的文本輸入、選擇或複選框。經過實現ControlValueAccessor 接口並將組件註冊爲 NG_VALUE_ACCESSOR,您能夠將自定義表單控件無縫地集成到模板驅動或響應表單中,就像它是本地表單同樣!git

ControlValueAccessor

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);
}

AbstractValueAccessor

咱們能夠把 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 };
}

Example

自定義一個 list 控件,能夠選擇年級事件

相關文章
相關標籤/搜索