angular : 自定义组件双向绑定 [(ngModel)]

NG_VALUE_ACCESSOR

用于为表单控件提供 ControlValueAccessor

interface ControlValueAccessor {
  writeValue(obj: any): void
  registerOnChange(fn: any): void
  registerOnTouched(fn: any): void
  setDisabledState(isDisabled: boolean)?: void
}

双向绑定 示例组件:

import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  forwardRef,
} from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
 
@Component({
  selector: 'my-input',
  styleUrls: ['./my.input.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MyInputComponent),
      multi: true,
    },
  ],
  template: `
    <input type="text" #inputElement 
        [(ngModel)]="value"  
        (ngModelChange)="modelChange($event)"/>
    <button (click)="clickMe()">change</button>
  `
})
export class MyInputComponent implements ControlValueAccessor {
  
  private onTouch = () => {};
  private onChange = (newValue: any) => {};
 
  value = '';
  index = 0; // for test manual change value
 
  constructor(
    private cdr: ChangeDetectorRef
  ) { }


  clickMe() {
    const v = 'index : ' + (++this.index);
    this.value = v;
    this.onChange(v);
  }

    
  modelChange(newValue: string) {
    this.onChange(newValue);
  }
 
  // ControlValueAccessor - 
  // 至少需要实现 writeValue, registerOnChange,registerOnTouched
  writeValue(v: any) {
    if (v !== this.value) {
      this.value = v;
    }
    // on push
    this.cdr.markForCheck();
  }
 
  registerOnChange(fn: any) {
    this.onChange = fn;
  }
 
  registerOnTouched(fn: any) {
    this.onTouch = fn;
  }
}

registerOnTouched 的参数 fn:

 registerOnChange 的参数 fn :

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值