Document 'own form controls' application
							parent
							
								
									7280703c4c
								
							
						
					
					
						commit
						b8b2f8a3e7
					
				|  | @ -1 +1,83 @@ | ||||||
| # Components Creating Own Form Controls | # Components Creating Own Form Controls | ||||||
|  | 
 | ||||||
|  | When a component becomes sufficiently complex, or the developer wishes to be able to reuse parts of it elsewhere, the component can be refactored into sub-components. One approach to binding such sub-components to their containing parent component is to pass the parent component's `FormGroup` in as an `@Input` parameter. Additionally, the data that each child sub-component needs is passed into an `@Input`. The children create their own `FormControls` as needed, and add them to the parent `FormGroup` provided to them. This approach greatly simplifies the code and template of the parent component: | ||||||
|  | 
 | ||||||
|  | ```typescript | ||||||
|  | export class AppComponent implements OnInit, OnDestroy { | ||||||
|  |   contact: Contact; | ||||||
|  |   form: FormGroup; | ||||||
|  | 
 | ||||||
|  |   private subscription: Subscription | ||||||
|  | 
 | ||||||
|  |   constructor(private fb: FormBuilder, private service: ContactService) { | ||||||
|  |     this.form = this.fb.group({}); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   public ngOnInit() { | ||||||
|  |     this.subscription = this.service.loadContact().subscribe((data: Contact) => { | ||||||
|  |       this.contact = data; | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ```html | ||||||
|  | <form [formGroup]="form"> | ||||||
|  |   <nested-forms-name | ||||||
|  |     [name]="contact.name" | ||||||
|  |     [parent]="form" | ||||||
|  |   ></nested-forms-name> | ||||||
|  |   <nested-forms-address-list | ||||||
|  |     [addresses]="contact.addresses" | ||||||
|  |     [parent]="form" | ||||||
|  |   ></nested-forms-address-list> | ||||||
|  | </form> | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | The `nested-forms-name` component is responsible for creating the form controls binding to the Contact's name, and the `nested-forms-address-list` component is responsible for iterating over the Contact's addresses and binding to them using the `nested-forms-address` (singular) component. For example, the `nested-forms-name` would be implented as so: | ||||||
|  | 
 | ||||||
|  | ```typescript | ||||||
|  | @Component({ | ||||||
|  |   selector: 'nested-forms-name', | ||||||
|  |   templateUrl: './name.component.html', | ||||||
|  |   styleUrls: ['./name.component.css'] | ||||||
|  | }) | ||||||
|  | export class NameComponent implements OnInit { | ||||||
|  | 
 | ||||||
|  |   @Input() name: Name; | ||||||
|  |   @Input() parent: FormGroup; | ||||||
|  | 
 | ||||||
|  |   group: FormGroup; | ||||||
|  | 
 | ||||||
|  |   constructor(private fb: FormBuilder) { | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   ngOnInit() { | ||||||
|  |     this.group = this.fb.group({ | ||||||
|  |       firstName: new FormControl(this.name ? this.name.firstName : ''), | ||||||
|  |       lastName: new FormControl(this.name ? this.name.lastName : ''), | ||||||
|  |       middleName: new FormControl(this.name ? this.name.middleName : ''), | ||||||
|  |       prefix: new FormControl(this.name ? this.name.prefix : ''), | ||||||
|  |       suffix: new FormControl(this.name ? this.name.suffix : ''), | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     if (this.parent) { | ||||||
|  |       this.parent.addControl('name', this.group); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Calling `this.parent.addControl(....)` is what ensures that the controls created in the child component are made part of the over-all form. | ||||||
|  | 
 | ||||||
|  | ## Pros | ||||||
|  | 
 | ||||||
|  | - The parent component is easy to understand and maintain | ||||||
|  | - Each child component encapsulates its form controls and template | ||||||
|  | - The child components can easily be re-used in other "parent" components | ||||||
|  | 
 | ||||||
|  | ## Cons | ||||||
|  | 
 | ||||||
|  | - The creation of the form controls is tightly coupled with the templates | ||||||
|  | - Since each child component encapsulates its form controls, the overall shape of the form data is not always clear | ||||||
|  | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue