Angular ControlValueAccessor - ngModel with Child Component

By Arvind Rai, May 17, 2023
The ControlValueAccessor is an interface that acts as a bridge between the Angular forms API and a native element in the DOM. We can create custom form control directive by implementing the ControlValueAccessor interface.
The ControlValueAccessor has following method declarations.
writeValue(obj: any): void : Writes a new value to the element.
registerOnChange(fn: any): void : Registers a callback function that is called when the control's value changes in the UI.
registerOnTouched(fn: any): void : Registers a callback function that is called by the forms API on initialization to update the form model on blur.
setDisabledState(isDisabled: boolean)?: void : Function that is called by the forms API when the control status changes to or from 'DISABLED'. 

On this page we will use ControlValueAccessor to bind ngModel with child component.

Complete Example

In our example we are creating parent and child component. The child component is implementing the ControlValueAccessor interface. Using its writeValue method, we are enabling child component to bind ngModel in parent component.
app.component.ts
import { Component } from "@angular/core";
import { Student } from "./student";

@Component({
  selector: 'app-root',
  template: `
      <app-student [ngModel]="students"></app-student>
  `
})
export class AppComponent {
  students: Student[] = [
    { name: 'Mohit', age: 25 },
    { name: 'Krishn', age: 30 }
  ];
} 
student-cvaccessor.component.ts
import { Component, forwardRef, Renderer2, ElementRef, Provider } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
import { Student } from "./student";

const CUSTOM_VALUE_ACCESSOR: Provider = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => StudentCVAccessorComponent),
  multi: true
}

@Component({
  selector: 'app-student',
  template: `
      <div *ngFor="let std of students">
         <p>{{std.name}} - {{std.age}}</p>
      </div>
    `,
  providers: [CUSTOM_VALUE_ACCESSOR]
})
export class StudentCVAccessorComponent implements ControlValueAccessor {
  students: Student[] = [];

  writeValue(obj: any) {
    this.students = obj;
  }
  registerOnChange(fn: any) {
  }
  registerOnTouched(fn: any) {
  }
  setDisabledState(isDisabled: boolean) {
  }
} 
student.ts
export interface Student {
    name?: String;
    age?: number;
} 
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { StudentCVAccessorComponent } from './student-cvaccessor.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule
  ],
  declarations: [
    AppComponent,
    StudentCVAccessorComponent
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { } 
Find the print screen of the output.
Angular ControlValueAccessor - ngModel with Child Component

Reference

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us