본문 바로가기

Frontend/Angular

Reusable Component - Reactive Forms Inputs

반응형

The reusability of components is one of the main advantages of using a framework such as Angular. Today, we will see how we can create an reusable input component in Angular.

Implementaion

Adding a Module

Add the ReactiveFormsModule in the module.ts class

Creating a Component

Add a component to get the inputs

 ng g c components/shared/input

 

To link the form controller and the DOM element, add inherit from the 'ControlValueAccessor' in the component class file we just created

import { ControlValueAccessor } from '@angular/forms';

Implement the class. We are not going to use any of the methods added so clean up and set aside.

 

For the dynimic values such as the type and label, use the @Input() to get the values from each component that is going to use this component.

 

Add a constructor and inject 'NgControl'. Note that, by default, the Angular will try to find the source service when there are multiple of them and we need to deactivate this behavior by adding @Self() infront to use the local service.

 

Lastly, Add the getter to return 'FormControl' type to prevent the type error

@Input() type: string = 'text';
@Input() label: string = '';

constructor(@Self() public controlDir: NgControl) {
  this.controlDir.valueAccessor = this;
}

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

get control(): FormControl {
  return this.controlDir.control as FormControl;
}

Go to the templet and add the code shown below (In the example, I used Bootstrap classes for visual effects)

<div class="form-floating mb-3">
  <input [type]="type" [formControl]="control" [placeholder]="label" class="form-control"
  [ngClass]="(control.touched) ? control.invalid ? 'is-invalid' : 'is-valid' : null">
  <label>{{label}}</label>
  <div *ngIf="control.touched && control.errors?.['required']" class="text-danger">{{label}} Required</div>
  <div *ngIf="control.errors?.['email']" class="text-danger">Please Enter a Valid Email</div>
</div>

Using the Component

Open or create a component that need a form input. And set up the reactive form with validations

form = new FormGroup({
  email: new FormControl('', [Validators.required, Validators.email]),
  password: new FormControl('', [Validators.required]),
})

In the template, add the reusable input tag and pass the control name and label

<app-input formControlName="email" [label]="'email'"></app-input>

In this wrting, we have seen how to make a reusable input component in Angular.

 

 

728x90
반응형