1. Create a provider in the custom component.

    providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => CustomSearchableTextComponent),
          multi: true
        }
    ]
  2. Override some functions of native input, and update model value inside the writeValue method

    // overwrite
      onTouched: () => void = () => { };
    
      onChange: (_: any) => void = (_: any) => { };
    
      writeValue(value: any): void {
        if (value !== undefined) {
          this.searchInput = value;
        }
      }
    
      // /**
      //  * Registers a callback function that should be called when the control's value changes in the UI.
      //  * @param fn
      //  */
      registerOnChange(fn: any): void {
        this.onChange = fn;
      }
    
      // /**
      //  * Registers a callback function that should be called when the control receives a blur event.
      //  * @param fn
      //  */
      registerOnTouched(fn: any): void {
        this.onTouched = fn;
      }
  3. add ngModelChange event handler and call onChange method

    onInputChange(e) {
        this.onChange(e);
      }
custom-searchable-text-input.ts
import { Component, OnInit, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-custom-searchable-text',
  templateUrl: './custom-searchable-text.component.html',
  styleUrls: ['./custom-searchable-text.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CustomSearchableTextComponent),
      multi: true
    }
  ]
})
export class CustomSearchableTextComponent implements OnInit {
  searchInput: string;

  constructor() { }

  ngOnInit(): void {
  }

  onInputChange(e) {
    // async model from outside to inside
    this.onChange(e);
  }

  // overwrite
  onTouched: () => void = () => { };

  onChange: (_: any) => void = (_: any) => { };

  writeValue(value: any): void {
    if (value !== undefined) {
      this.searchInput = value;
    }
  }

  // /**
  //  * Registers a callback function that should be called when the control's value changes in the UI.
  //  * @param fn
  //  */
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  // /**
  //  * Registers a callback function that should be called when the control receives a blur event.
  //  * @param fn
  //  */
  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }
}
custom-searchable-text-input.html
<input
  type="text"
  [(ngModel)]="searchInput"
  [required]="isRequired"
  (ngModelChange)="onInputChange($event)"
/>
Parent reference
<app-custom-searchable-text
  [(ngModel)]="searchInput"
  #test="ngModel"
></app-custom-searchable-text>

abby_mrs
510 声望12 粉丝