You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 3.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. # Parent Component Creates Form; Child Components Define Structure
  2. 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.
  3. In many ways, this approach is a hybrid between the Parent Form and Global Form approaches.
  4. ```typescript
  5. export class AppComponent implements OnInit, OnDestroy {
  6. contact: Contact;
  7. form: FormGroup;
  8. private subscription: Subscription;
  9. constructor(private service: ContactService, private fb: FormBuilder) {}
  10. public ngOnInit() {
  11. this.subscription = this.service
  12. .loadContact()
  13. .subscribe((data: Contact) => {
  14. this.contact = data;
  15. this.form = this.fb.group({
  16. name: NameComponent.buildForm(data.name),
  17. addresses: AddressListComponent.buildForm(data.addresses),
  18. });
  19. });
  20. }
  21. }
  22. ```
  23. The HTML templating will be identical to the Global Form approach.
  24. ## Static Form Builder Methods
  25. 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.
  26. ### Name Component
  27. ```typescript
  28. static buildForm(name: Name): FormGroup {
  29. return new FormGroup({
  30. firstName: new FormControl(name ? name.firstName : ''),
  31. lastName: new FormControl(name ? name.lastName : ''),
  32. middleName: new FormControl(name ? name.middleName : ''),
  33. prefix: new FormControl(name ? name.prefix : ''),
  34. suffix: new FormControl(name ? name.suffix : ''),
  35. });
  36. }
  37. ```
  38. ### Address List Component
  39. ```typescript
  40. static buildForm(addresses: Address[]): FormArray {
  41. const list: FormArray = new FormArray([]);
  42. if (addresses) {
  43. addresses.forEach(addr => {
  44. list.push(AddressComponent.buildForm(addr));
  45. });
  46. }
  47. return list;
  48. }
  49. ```
  50. ### Address Component
  51. ```typescript
  52. static buildForm(addr: Address): FormGroup {
  53. return new FormGroup({
  54. line1: new FormControl(addr ? addr.line1 : ''),
  55. line2: new FormControl(addr ? addr.line2 : ''),
  56. city: new FormControl(addr ? addr.city : ''),
  57. state: new FormControl(addr ? addr.state : ''),
  58. postalCode: new FormControl(addr ? addr.postalCode : ''),
  59. });
  60. }
  61. ```
  62. ## Pros
  63. - The child components encapsulate the form controls and their display, while keeping the form creation logic separate from the actual template rendering
  64. - The child components can easily be re-used
  65. ## Cons
  66. - The overall shape of the form from the parent component's perspective is not always clear