|
261 | 261 | |253| [Is it mandatory to use injectable on every service class?](#is-it-mandatory-to-use-injectable-on-every-service-class)|
|
262 | 262 | |254| [What is an optional dependency?](#what-is-an-optional-dependency)|
|
263 | 263 | |255| [What are the types of injector hierarchies?](#what-are-the-types-of-injector-hierarchies)|
|
264 |
| -|256| [What are dynamic forms?](#what-are-dynamic-forms)| |
265 |
| -|257| [What are the differences between reactive forms and template driven forms?](#what-are-the-differences-between-reactive-forms-and-template-driven-forms)| |
266 |
| -|258| [](#)| |
267 |
| -|259| [](#)| |
268 |
| -|260| [](#)| |
269 |
| -|261| [](#)| |
270 |
| -|262| [](#)| |
| 264 | +|256| [What are reactive forms?](#what-are-reactive-forms)| |
| 265 | +|257| [What are dynamic forms?](#what-are-dynamic-forms)| |
| 266 | +|258| [What are template driven forms?](#what-are-template-driven-forms)| |
| 267 | +|259| [What are the differences between reactive forms and template driven forms?](#what-are-the-differences-between-reactive-forms-and-template-driven-forms)| |
| 268 | +|260| [What are the different ways to group form controls?](#what-are-the-different-ways-to-group-form-controls)| |
| 269 | +|261| [How do you update specific properties of a form model?](#how-do-you-update-specific-properties-of-a-form-model)| |
| 270 | +|262| [What is the purpose of FormBuilder?](#what-is-the-purpose-of-formbuilder)| |
271 | 271 | |263| [](#)|
|
272 | 272 | |264| [](#)|
|
273 | 273 | |265| [](#)|
|
|
3894 | 3894 | 255. ### What are the types of injector hierarchies?
|
3895 | 3895 | There are two types of injector hierarchies in Angular
|
3896 | 3896 |
|
3897 |
| - 1. ModuleInjector hierarchy: It configure on a module level using an @NgModule() or @Injectable() annotation. |
3898 |
| - 2. ElementInjector hierarchy: It created implicitly at each DOM element. Also it is empty by default unless you configure it in the providers property on @Directive() or @Component(). |
| 3897 | + 1. **ModuleInjector hierarchy:** It configure on a module level using an @NgModule() or @Injectable() annotation. |
| 3898 | + 2. **ElementInjector hierarchy:** It created implicitly at each DOM element. Also it is empty by default unless you configure it in the providers property on @Directive() or @Component(). |
3899 | 3899 |
|
3900 | 3900 | **[⬆ Back to Top](#table-of-contents)**
|
3901 | 3901 |
|
3902 |
| -256. ### What are dynamic forms? |
| 3902 | +256. ### What are reactive forms? |
| 3903 | + Reactive forms is a model-driven approach for creating forms in a reactive style(form inputs changes over time). These are built around observable streams, where form inputs and values are provided as streams of input values. Let's follow the below steps to create reactive forms, |
| 3904 | + 1. Register the reactive forms module which declares reactive-form directives in your app |
| 3905 | + ```js |
| 3906 | + import { ReactiveFormsModule } from '@angular/forms'; |
| 3907 | +
|
| 3908 | + @NgModule({ |
| 3909 | + imports: [ |
| 3910 | + // other imports ... |
| 3911 | + ReactiveFormsModule |
| 3912 | + ], |
| 3913 | + }) |
| 3914 | + export class AppModule { } |
| 3915 | + ``` |
| 3916 | + 2. Create a new FormControl instance and save it in the component. |
| 3917 | + ```js |
| 3918 | + import { Component } from '@angular/core'; |
| 3919 | + import { FormControl } from '@angular/forms'; |
| 3920 | +
|
| 3921 | + @Component({ |
| 3922 | + selector: 'user-profile', |
| 3923 | + styleUrls: ['./user-profile.component.css'] |
| 3924 | + }) |
| 3925 | + export class UserProfileComponent { |
| 3926 | + userName = new FormControl(''); |
| 3927 | + } |
| 3928 | + ``` |
| 3929 | + 3. Register the FormControl in the template. |
| 3930 | + ```js |
| 3931 | + <label> |
| 3932 | + User name: |
| 3933 | + <input type="text" [formControl]="userName"> |
| 3934 | + </label> |
| 3935 | + ``` |
| 3936 | + Finally, the component with reactive form control appears as below, |
| 3937 | + ```js |
| 3938 | + import { Component } from '@angular/core'; |
| 3939 | + import { FormControl } from '@angular/forms'; |
| 3940 | +
|
| 3941 | + @Component({ |
| 3942 | + selector: 'user-profile', |
| 3943 | + styleUrls: ['./user-profile.component.css'] |
| 3944 | + template: ` |
| 3945 | + <label> |
| 3946 | + User name: |
| 3947 | + <input type="text" [formControl]="userName"> |
| 3948 | + </label> |
| 3949 | + ` |
| 3950 | + }) |
| 3951 | + export class UserProfileComponent { |
| 3952 | + userName = new FormControl(''); |
| 3953 | + } |
| 3954 | + ``` |
| 3955 | +
|
| 3956 | + **[⬆ Back to Top](#table-of-contents)** |
| 3957 | +
|
| 3958 | +257. ### What are dynamic forms? |
3903 | 3959 | Dynamic forms is a pattern in which we build a form dynamically based on metadata that describes a business object model. You can create them based on reactive form API.
|
3904 | 3960 | **[⬆ Back to Top](#table-of-contents)**
|
3905 | 3961 |
|
3906 |
| -257. ### What are the differences between reactive forms and template driven forms? |
| 3962 | +
|
| 3963 | +258. ### What are template driven forms? |
| 3964 | +
|
| 3965 | + **[⬆ Back to Top](#table-of-contents)** |
| 3966 | +
|
| 3967 | +259. ### What are the differences between reactive forms and template driven forms? |
3907 | 3968 | Below are the main differences between reactive forms and template driven forms
|
3908 | 3969 |
|
3909 | 3970 | | Feature | Reactive | Template-Driven |
|
3910 | 3971 | |---- |---- | --------- |
|
3911 | 3972 | | Form model setup | Created(FormControl instance) in component explicitly | Created by directives |
|
3912 | 3973 | | Data updates | Synchronous | Asynchronous |
|
3913 | 3974 | | Form custom validation | Defined as Functions | Defined as Directives |
|
| 3975 | + | Testing | No interaction with change detection cycle | Need knowledge of the change detection process | |
3914 | 3976 | | Mutability | Immutable(by always returning new value for FormControl instance) | Mutable(Property always modified to new value) |
|
3915 | 3977 | | Scalability | More scalable using low-level APIs | Less scalable using due to abstraction on APIs|
|
3916 | 3978 |
|
3917 | 3979 | **[⬆ Back to Top](#table-of-contents)**
|
3918 | 3980 |
|
3919 |
| -258. ### ? |
3920 | 3981 |
|
3921 |
| - **[⬆ Back to Top](#table-of-contents)** |
| 3982 | +260. ### What are the different ways to group form controls? |
| 3983 | + Reactive forms provide two ways of grouping multiple related controls. |
| 3984 | + 1. **FormGroup**: It defines a form with a fixed set of controls those can be managed together in an one object. It has same properties and methods similar to a FormControl instance. |
| 3985 | + This FormGroup can be nested to create complex forms as below. |
| 3986 | + ```js |
| 3987 | + import { Component } from '@angular/core'; |
| 3988 | + import { FormGroup, FormControl } from '@angular/forms'; |
3922 | 3989 |
|
3923 |
| -259. ### ? |
| 3990 | + @Component({ |
| 3991 | + selector: 'user-profile', |
| 3992 | + templateUrl: './user-profile.component.html', |
| 3993 | + styleUrls: ['./user-profile.component.css'] |
| 3994 | + }) |
| 3995 | + export class UserProfileComponent { |
| 3996 | + userProfile = new FormGroup({ |
| 3997 | + firstName: new FormControl(''), |
| 3998 | + lastName: new FormControl(''), |
| 3999 | + address: new FormGroup({ |
| 4000 | + street: new FormControl(''), |
| 4001 | + city: new FormControl(''), |
| 4002 | + state: new FormControl(''), |
| 4003 | + zip: new FormControl('') |
| 4004 | + }) |
| 4005 | + }); |
3924 | 4006 |
|
3925 |
| - **[⬆ Back to Top](#table-of-contents)** |
| 4007 | + onSubmit() { |
| 4008 | + // Store this.userProfile.value in DB |
| 4009 | + } |
| 4010 | + } |
| 4011 | + ``` |
| 4012 | + ```html |
| 4013 | + <form [formGroup]="userProfile" (ngSubmit)="onSubmit()"> |
| 4014 | +
|
| 4015 | + <label> |
| 4016 | + First Name: |
| 4017 | + <input type="text" formControlName="firstName"> |
| 4018 | + </label> |
| 4019 | +
|
| 4020 | + <label> |
| 4021 | + Last Name: |
| 4022 | + <input type="text" formControlName="lastName"> |
| 4023 | + </label> |
| 4024 | +
|
| 4025 | + <div formGroupName="address"> |
| 4026 | + <h3>Address</h3> |
| 4027 | +
|
| 4028 | + <label> |
| 4029 | + Street: |
| 4030 | + <input type="text" formControlName="street"> |
| 4031 | + </label> |
| 4032 | +
|
| 4033 | + <label> |
| 4034 | + City: |
| 4035 | + <input type="text" formControlName="city"> |
| 4036 | + </label> |
| 4037 | +
|
| 4038 | + <label> |
| 4039 | + State: |
| 4040 | + <input type="text" formControlName="state"> |
| 4041 | + </label> |
| 4042 | +
|
| 4043 | + <label> |
| 4044 | + Zip Code: |
| 4045 | + <input type="text" formControlName="zip"> |
| 4046 | + </label> |
| 4047 | + </div> |
| 4048 | + <button type="submit" [disabled]="!userProfile.valid">Submit</button> |
| 4049 | +
|
| 4050 | + </form> |
| 4051 | + ``` |
| 4052 | + 2. **FormArray:** It defines a dynamic form in an array format, where you can add and remove controls at run time. This is useful for dynamic forms when you don’t know how many controls will be present within the group. |
| 4053 | + ```js |
| 4054 | + import { Component } from '@angular/core'; |
| 4055 | + import { FormArray, FormControl } from '@angular/forms'; |
3926 | 4056 |
|
3927 |
| -260. ### ? |
| 4057 | + @Component({ |
| 4058 | + selector: 'order-form', |
| 4059 | + templateUrl: './order-form.component.html', |
| 4060 | + styleUrls: ['./order-form.component.css'] |
| 4061 | + }) |
| 4062 | + export class OrderFormComponent { |
| 4063 | + constructor () { |
| 4064 | + this.orderForm = new FormGroup({ |
| 4065 | + firstName: new FormControl('John', Validators.minLength(3)), |
| 4066 | + lastName: new FormControl('Rodson'), |
| 4067 | + items: new FormArray([ |
| 4068 | + new FormControl(null) |
| 4069 | + ]) |
| 4070 | + }); |
| 4071 | + } |
3928 | 4072 |
|
3929 |
| - **[⬆ Back to Top](#table-of-contents)** |
| 4073 | + onSubmitForm () { |
| 4074 | + // Save the items this.orderForm.value in DB |
| 4075 | + } |
3930 | 4076 |
|
3931 |
| -261. ### ? |
| 4077 | + onAddItem () { |
| 4078 | + this.orderForm.controls |
| 4079 | + .items.push(new FormControl(null)); |
| 4080 | + } |
3932 | 4081 |
|
| 4082 | + onRemoveItem (index) { |
| 4083 | + this.orderForm.controls['items'].removeAt(index); |
| 4084 | + } |
| 4085 | + } |
| 4086 | + ``` |
| 4087 | + ```html |
| 4088 | + <form [formControlName]="orderForm" (ngSubmit)="onSubmit()"> |
| 4089 | +
|
| 4090 | + <label> |
| 4091 | + First Name: |
| 4092 | + <input type="text" formControlName="firstName"> |
| 4093 | + </label> |
| 4094 | +
|
| 4095 | + <label> |
| 4096 | + Last Name: |
| 4097 | + <input type="text" formControlName="lastName"> |
| 4098 | + </label> |
| 4099 | +
|
| 4100 | + <div> |
| 4101 | + <p>Add items</p> |
| 4102 | + <ul formArrayName="items"> |
| 4103 | + <li *ngFor="let item of orderForm.controls.items.controls; let i = index"> |
| 4104 | + <input type="text" formControlName="{{i}}"> |
| 4105 | + <button type="button" title="Remove Item" (click)="onRemoveItem(i)">Remove</button> |
| 4106 | + </li> |
| 4107 | + </ul> |
| 4108 | + <button type="button" (click)="onAddItem"> |
| 4109 | + Add an item |
| 4110 | + </button> |
| 4111 | + </div> |
| 4112 | + ``` |
| 4113 | +
|
| 4114 | + **[⬆ Back to Top](#table-of-contents)** |
| 4115 | +
|
| 4116 | +261. ### How do you update specific properties of a form model? |
| 4117 | + You can use `patchValue()` method to update specific properties defined in the form model. For example,you can update the name and street of certain profile on click of the update button as shown below. |
| 4118 | + ```js |
| 4119 | + updateProfile() { |
| 4120 | + this.userProfile.patchValue({ |
| 4121 | + firstName: 'John', |
| 4122 | + address: { |
| 4123 | + street: '98 Crescent Street' |
| 4124 | + } |
| 4125 | + }); |
| 4126 | + } |
| 4127 | + ``` |
| 4128 | + ```html |
| 4129 | + <button (click)="updateProfile()">Update Profile</button> |
| 4130 | + ``` |
3933 | 4131 | **[⬆ Back to Top](#table-of-contents)**
|
| 4132 | + You can also use `setValue` method to update properties. |
3934 | 4133 |
|
3935 |
| -262. ### ? |
| 4134 | + **Note:** Remember to update the properties against the exact model structure. |
3936 | 4135 |
|
| 4136 | +262. ### What is the purpose of FormBuilder? |
| 4137 | + FormBuilder is used as syntactic sugar for easily creating instances of a FormControl, FormGroup, or FormArray. This is helpful to reduce the amount of boilerplate needed to build complex reactive forms. It is available as an injectable helper class of the `@angular/forms` package. |
| 4138 | + For example, the user profile component creation becomes easier as shown here. |
| 4139 | + ```js |
| 4140 | + export class UserProfileComponent { |
| 4141 | + profileForm = this.formBuilder.group({ |
| 4142 | + firstName: [''], |
| 4143 | + lastName: [''], |
| 4144 | + address: this.formBuilder.group({ |
| 4145 | + street: [''], |
| 4146 | + city: [''], |
| 4147 | + state: [''], |
| 4148 | + zip: [''] |
| 4149 | + }), |
| 4150 | + }); |
| 4151 | + constructor(private formBuilder: FormBuilder) { } |
| 4152 | + } |
| 4153 | + ``` |
3937 | 4154 | **[⬆ Back to Top](#table-of-contents)**
|
3938 | 4155 |
|
3939 | 4156 | 263. ### ?
|
|
0 commit comments