Angular — Complex and Dynamic Form Design Study (Part 1)

Ben Cheng
3 min readJun 29, 2019

--

Introduction

In Modern Web Application, a from could be very very very complicated. It would require a fancy layout, dynamic, validated, functional and also performance.

All make the Web Application Development Difficult and cost so much resource. All the developed framework tried to make it easier but still very very very difficult.

Here, I would like to share some approaches to handle it in Angular.

  • Form Group as Parameter (One Form Group Solution)
  • Self Register Form Group (One Form Group Solution)
  • Angular Input Output Handling (Centralized Model Solution)
  • Context Service (Centralized Model Solution)
  • NgRx Store (Centralized Model Solution)

Form Group as Parameter

Self Register Form Group

The mother form is required to provide the addControl mechanism to the form when the child form is initialized and destroyed. For example, the ngFor and ngIf situation should be catered.

Mother Form

abstract class MotherForm {
form: FormGroup;
constructor(){
this.from = this.initializeForm();
}


initializeForm(): FormGroup {
return new FormGroup({})
}
addControlGroup(name: string, formGroup: AbstractControl): void {
this.form.addControl(name, formGroup);
}
removeControl(name: string){
this.form.removeControl(name);
}
}

Children Form

abstract class ChildrenForm implements OnInit, OnDestroy {
@Input()
intialValue: any
form: FormGroup
constructor(@Host private _motherForm: MotherForm){
this.form = this.initializeForm();
}
initializeForm() : FormGroup{
return new FormGroup({});
}
getFormName(): string {
return 'emptyForm'
}
ngOnInit(){
if (this.intialValue){
this.form.setValue(this.initialValue)
}
this._motherForm.addControlGroup(this.getFormName(), this.form);
}
ngOnDestroy(){
this._motherForm.removeControlGroup(this.getFormName());
}
}

Now, The implementation class would leverage these abstract class for self registration.

app-self-register.component.ts

import { Component, OnInit } from '@angular/core';
import MotherForm from './mother-form';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-self-register',
templateUrl: './self-register.component.html',
styleUrls: ['./self-register.component.css']
})
export class SelfRegisterComponent extends MotherForm {
constructor() {
super();
}
initializeForm(){
return new FormGroup({
name: new FormControl('')
})
}
}

app-self-register.component.html

<form [formGroup]="form">
<input formControlName="name"/>
<app-self-register-children1></app-self-register-children1>
</form>
{{form.value | json}}

self-register-children1.component.ts

import { FormGroup, FormControl } from '@angular/forms';
import { Component, OnInit, Host } from '@angular/core';
import ChildrenForm from '../children-form';
import { SelfRegisterComponent } from '../self-register.component';
@Component({
selector: 'app-self-register-children1',
templateUrl: './self-register-children1.component.html',
styleUrls: ['./self-register-children1.component.css']
})
export class SelfRegisterChildren1Component extends ChildrenForm {
constructor(@Host() _motherForm: SelfRegisterComponent) {
super(_motherForm);
}
initializeForm(): FormGroup{
return new FormGroup({
name: new FormControl('')
})
}
getFormName(): string {
return "selfRegisterChildren1";
}
}

self-register-children1.component.html

<form [formGroup]="form">
<input formControlName="name"/>
</form>

--

--

Ben Cheng

A developer in Hong Kong. Learning and rethinking as a developer. Welcome to contact me and make friend with me. Cooperation is welcome.