Angular-自定义formControl

介绍

angular的表单,先复习一下:https://angular.cn/guide/forms-overview
接下来看,它一般是长这样的:

请选择颜色 多选组件 ...

注意到那里,
像input、textarea、nz-select组件,直接指定formControlName,是可以正常工作的。
但假如组件是自定义的,此时,要做特殊处理,如何跟form进行通讯。

如何做

  • 有些时候,对于某些已有组件,指定ngDefaultControl,即可正常工作:

  • 如果还是不行,那么abc组件类,需要自行实现ControlValueAccessor接口,才可以通过指定formControlName去正常使用。
    ControlValueAccessor接口的三个方法:
    writeValue(obj: any): void:表单为你设值时会调用。在这里处理表单带过来的值obj
    registerOnChange(fn: any): void:在这里,保存fn函数。当你作为一个表单项,改变了值,比如有个文本框输入了'test',就需要通知给表单(调用fn函数)
    registerOnTouched(fn: any): void:在这里,保存fn函数。当你作为一个表单项,完成了一次输入交互后,就需要调用这个fn函数

代码示例

有注释,实际上也很简单:

import { Component, OnInit, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-form-checkbox',
  templateUrl: './form-checkbox.component.html',
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: AppFormCheckboxComponent,
    multi: true
  }]
})
// 以上代码直接拷回去
// .html自行实现
export class AppFormCheckboxComponent implements ControlValueAccessor {

  value = []; // 组件对应的 “ ngModel ”
  onChangeListener; // 改变值回调
  onTouchedListener; // 交互回调

  constructor() {
  }

  writeValue(obj: any): void {
    this.value = obj; // form中给你设置了obj值,根据obj,去更新组件/UI
  }

  registerOnChange(fn: any): void {
    this.onChangeListener = fn; // 保存这个函数
  }

  registerOnTouched(fn: any): void {
    this.onTouchedListener = fn; // 保存这个函数
  }

  /**
   * 自定义当组件发生改变时,会调用的方法
   */
  onChange(payload) {
    this.value = payload;
    this.onChangeListener(payload); // 告诉form,你的表单值改变成了payload
    this.onTouchedListener(); // 告诉form,你的表单有交互发生
  }

}

参考

也可以参考下这篇文章:https://segmentfault.com/a/1190000014129567

你可能感兴趣的:(Angular-自定义formControl)