|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- # Parent Component Creates Form; Child Components Define Structure
-
- Another approach for refactoring a component into child sub-components where the parent component is responsible for creating the entre Reactive Form would be to define static factory methods within each child component rather than within a full-fledged service. As with the [Parent Component Creates Form and Passes Form Controls Into Child Components (Global Form)](../global-form/README.md) approach, the appropriate form controls would be passed into the children.
-
- In many ways, this approach is a hybrid between the Parent Form and Global Form approaches.
-
- ```typescript
- export class AppComponent implements OnInit, OnDestroy {
- contact: Contact;
- form: FormGroup;
-
- private subscription: Subscription;
-
- constructor(private service: ContactService, private fb: FormBuilder) {}
-
- public ngOnInit() {
- this.subscription = this.service
- .loadContact()
- .subscribe((data: Contact) => {
- this.contact = data;
- this.form = this.fb.group({
- name: NameComponent.buildForm(data.name),
- addresses: AddressListComponent.buildForm(data.addresses),
- });
- });
- }
- }
- ```
-
- The HTML templating will be identical to the Global Form approach.
-
- ## Static Form Builder Methods
-
- Rather than having a separate factory service, this approach uses static methods on each of the child sub-classes. This approach intentionally couples the logic for creating a sub-form structure with the component that would display it, keeping the logic in one place rather than separating it between components and an otherwise unrelated service. The rule-of-thumb in this approach is that the component which needs to display the form to a user will best know what the structure of that form needs to be.
-
- ### Name Component
-
- ```typescript
- static buildForm(name: Name): FormGroup {
- return new FormGroup({
- firstName: new FormControl(name ? name.firstName : ''),
- lastName: new FormControl(name ? name.lastName : ''),
- middleName: new FormControl(name ? name.middleName : ''),
- prefix: new FormControl(name ? name.prefix : ''),
- suffix: new FormControl(name ? name.suffix : ''),
- });
- }
- ```
-
- ### Address List Component
-
- ```typescript
- static buildForm(addresses: Address[]): FormArray {
- const list: FormArray = new FormArray([]);
-
- if (addresses) {
- addresses.forEach(addr => {
- list.push(AddressComponent.buildForm(addr));
- });
- }
-
- return list;
- }
- ```
-
- ### Address Component
-
- ```typescript
- static buildForm(addr: Address): FormGroup {
- return new FormGroup({
- line1: new FormControl(addr ? addr.line1 : ''),
- line2: new FormControl(addr ? addr.line2 : ''),
- city: new FormControl(addr ? addr.city : ''),
- state: new FormControl(addr ? addr.state : ''),
- postalCode: new FormControl(addr ? addr.postalCode : ''),
- });
- }
- ```
-
- ## Pros
-
- - The child components encapsulate the form controls and their display, while keeping the form creation logic separate from the actual template rendering
- - The child components can easily be re-used
-
- ## Cons
-
- - The overall shape of the form from the parent component's perspective is not always clear
|