Monday, 28 November 2016

Reactive forms in Angular 2

Angular (aka Angular2) gives us two ways to create forms: template driven and model driven (aka reactive). The model driven approach provides several advantages:
  •         They are more testable
  •         They are more dynamic
  •                Forms can be built at runtime “on the fly” without changing the application code
  •          They are easier to maintain
  •                              All the logic is in one place

Reactive/model-driven forms do not use Angular directives such as “ngModel”, “required”, “disabled” etc. Instead of relying on the Angular framework to power things for us, we use the underlying APIs instead. Instead of binding Object models to directives like template-driven forms, we declare and create our own instances inside a component class and construct our own JavaScript models. This has much more power and is extremely productive to work with as it allows us to write testable, easier to understand code that keeps all logic in the same place instead of scattering it around different form templates.

Importing the ReactiveFormsModule

The first step is to import the ReactiveFormsModule (as opposed to the standard FormsModule) into the module that will contain your model-driven form. e.g.

import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
  imports: [BrowserModule, ReactiveFormsModule….

FormControl

Each element on the form is mapped to an instance of the FormControl class. It tracks the value and validation status as well as offering a set of API methods for accessing the form data.
The declaration of a FormControl class takes as parameters (in this order):
  1. Initial value & state (e.g. disabled)
  2. Any synchronous validator, or array of sync validators
  3. Any asynchronous validator, or array of async validators


Here is an example declaration:
zipCode: FormControl;
zipCode = new FormControl({value: '', disabled: false}, validators.required);

This code declares a variable of type FormControl, then assigns it to a new instance of the FormControl class which has an initial empty value of and is not disabled. It also has a sync validator of “required”.

FormGroup

A FormGroup is just that – a grouping of FormControl instances. At the highest level it represents the form itself, but FormGroups can be nested to represent sub-groupings that can make the form easier to manage. Other advantages are:
  •        Allows validation at a FormGroup level. E.g. the “submit” button could be enabled/disabled based on the valid status of the FormGroup, which in turn would depend on the valid status of the FormControls in the FormGroup. It would also allow us to implement custom validation
  •          FormGroup provides a convenient way to declare many controls at once. An array of FormControls can be constructed, e.g. from reference data or a backend service, then passed into the constructor of the FormGroup

Example declaration:
    const form = new FormGroup({
         firstName: new FormControl(‘Tim’, Validators.minLength(2)),
         lastName: new FormControl('Hodkinson'),
       });
       console.log(form.value);   // {firstName: 'Tim', lastName; 'Hodkinson'}
       console.log(form.status);  // 'VALID'

 

Binding to the template

The final step is to bind the code to the html template. We do this using the Angular [formGroup] directive  to bind an html form on the template to the FormGroup. We can then use the formControlName  directive to bind individual FormControls in the FormGroup to the html form control elements using the name key. For example:


<form (ngSubmit)="onSubmit()" [formGroup]="form">
      <label>Firstname:</label>
      <input type="text" formControlName="firstName">
      <label>Lastname:</label>
      <input type="text" formControlName="lastName">
      <button type="submit">Submit</button>

</form>

In the code above [formGroup] binds the html form to the FormGroup we declared in the last section, which we called “form”. The inputs are then bound to the firstName and lastName FormControls in the “form” FormGroup.

No comments:

Post a Comment