@@ -16,11 +16,11 @@ a#toc
1616 - [Import the _ReactiveFormsModule_](#import)
1717 - [Update the app to use the form component](#update)
1818 - [Introduction to _FormBuilder_](#formbuilder)
19- - [Group _FormControls_ ](#grouping)
19+ - [Nested FormGroups ](#grouping)
2020 - [Inspect _FormControl_ properties](#properties)
2121 - [Set form model data using _setValue_ and _patchValue_](#set-data)
2222 - [Use _FormArray_ to present an array of _FormGroups_](#form-array)
23- - [Watch control changes](#watch -control)
23+ - [Observe control changes](#observe -control)
2424 - [Save form data](#save)
2525
2626 Try the <live-example plnkr="final" title="Reactive Forms (final) in Plunker">Reactive Forms live-example</live-example>.
@@ -85,42 +85,22 @@ a#intro
8585 You don't push and pull data values. Angular handles that for you with `ngModel`.
8686 Angular updates the mutable _data model_ with user changes as they happen.
8787
88- Both data binding and the mutable _data model_ are contrary to reactive principles.
89- In fact, the `ngModel` directive is only available in the `FormsModule`, not in the `ReactiveFormsModule`.
90-
88+ When writing in a reactive style, you determine the timing and flow of data between
89+ the data model and the screen. You rarely, if ever, use two-way data binding.
90+ For this reason, the ngModel directive is not part of the ReactiveFormsModule.
91+
9192 These differences reflect two architectural paradigms,
9293 with their own strengths and weaknesses,
9394 and you are free to choose between them.
9495
9596 The balance of this _reactive forms_ guide assumes the _reactive_ paradigm and
96- concentrates exclusively on the reactive forms technique . For
97+ concentrates exclusively on the reactive forms techniques . For
9798 information on _template driven forms_, see the [Template Guide](forms.html).
9899
99- You'll learn about reactive forms by building one from scratch,
100- with instances of the Angular form classes.
101-
102- ### Essential form classes
103-
104- Before you begin, it may be helpful to read a brief description of the core form classes.
105-
106- * [_AbstractControl_](../api/forms/index/AbstractControl-class.html-class.html "API Reference: AbstractControl")
107- is the abstract base class for the three concrete form control classes:
108- `FormControl`, `FormGroup`, and `FormArray`.
109- It provides their common behaviors and properties, some of which are _observable_.
110-
111- * [_FormControl_](../api/forms/index/FormControl-class.html "API Reference: FormControl")
112- tracks the value and validity status of an _individual_ form control.
113- It corresponds to an HTML form control such as an input box or selector.
114-
115- * [_FormGroup_](../api/forms/index/FormGroup-class.html "API Reference: FormGroup")
116- tracks the value and validity state of a _group_ of `AbstractControl` instances.
117- The group's properties include its child controls.
118- The top-level form in your component is a `FormGroup`.
119-
120- * [_FormArray_](../api/forms/index/FormArray-class.html "API Reference: FormArray")
121- tracks the value and validity state of a numerically indexed _array_ of `AbstractControl` instances.
100+ You'll learn about reactive forms by building one from scratch.
122101
123- You'll learn more about these classes as you build your first reactive form.
102+ In the next section, you'll prepare your project for reactive forms.
103+ Then you'll [learn about the Angular form classes](#essentials) and how to use them in a reactive form.
124104
125105.l-main-section
126106a#setup
@@ -170,7 +150,7 @@ a#create-component
170150+ makeExample('reactive-forms/ts/app/hero-detail-versions.component.ts' , 'v1' ,'app/hero-detail.component.ts (excerpt)' )( format ="." )
171151
172152:marked
173- Inside the `FormGroup`, called `heroForm`, is a `FormControl` called `name`.
153+ Here you are creating a `FormGroup` called `heroForm` with a child `FormControl` called `name`.
174154 It will be bound in the template to an HTML `input` box for the hero name.
175155
176156 A `FormControl` constructor accepts three, optional arguments:
@@ -195,9 +175,11 @@ a#create-template
195175:marked
196176 The `novalidate` attribute in the `<form>` element prevents the browser
197177 from attempting native HTML validations.
198- The `[formGroup]="heroForm"` tells Angular that the form element
199- is associated with the `heroForm` property of the component class.
200- The `formControlName="name"` associates the `input` element with the `name` control inside the `heroForm`.
178+
179+ `formGroup` is a reactive form directive that takes an existing
180+ `FormGroup` instance and associates it with an HTML element.
181+ In this case, it will associate the `FormGroup` we saved as
182+ `heroForm` with the form element.
201183
202184.l-sub-section
203185 :marked
@@ -210,9 +192,8 @@ a#import
210192:marked
211193 ## Import the _ReactiveFormsModule_
212194
213- The `HeroDetailComponent` template uses directives from
214- the `ReactiveFormsModule` in the `@angular/forms` library
215- so you must add it to the `imports` array of the `NgModule` that declares that component.
195+ The HeroDetailComponent template uses `formGroup` and `formControlName`
196+ directives from the `ReactiveFormsModule`.
216197
217198 In this sample, you declare the `HeroDetailComponent` in the `AppModule`.
218199 Therefore, do the following three things in `app.module.ts`:
@@ -230,6 +211,31 @@ a#update
230211 Revise the `AppComponent` template so it displays the `HeroDetailComponent`.
231212+ makeExample('reactive-forms/ts/app/app.component.1.ts' , '' ,'app/app.component.ts' )( format ="." )
232213
214+ a#essentials
215+ :marked
216+ ### Essential form classes
217+ It may be helpful to read a brief description of the core form classes.
218+
219+ * [_AbstractControl_](../api/forms/index/AbstractControl-class.html-class.html "API Reference: AbstractControl")
220+ is the abstract base class for the three concrete form control classes:
221+ `FormControl`, `FormGroup`, and `FormArray`.
222+ It provides their common behaviors and properties, some of which are _observable_.
223+
224+ * [_FormControl_](../api/forms/index/FormControl-class.html "API Reference: FormControl")
225+ tracks the value and validity status of an _individual_ form control.
226+ It corresponds to an HTML form control such as an input box or selector.
227+
228+ * [_FormGroup_](../api/forms/index/FormGroup-class.html "API Reference: FormGroup")
229+ tracks the value and validity state of a _group_ of `AbstractControl` instances.
230+ The group's properties include its child controls.
231+ The top-level form in your component is a `FormGroup`.
232+
233+ * [_FormArray_](../api/forms/index/FormArray-class.html "API Reference: FormArray")
234+ tracks the value and validity state of a numerically indexed _array_ of `AbstractControl` instances.
235+
236+ You'll learn more about these classes as you work through this guide.
237+
238+
233239:marked
234240 ### Style the app
235241 You used bootstrap CSS classes in the template HTML of both the `AppComponent` and the `HeroDetailComponent`.
@@ -270,7 +276,6 @@ figure.image-display
270276 Great! You have the basics of a form.
271277
272278 In real life apps, forms get big fast.
273- The way you are creating `FormControls` currently is both tedious and hard to maintain.
274279 `FormBuilder` makes form development and maintenance easier.
275280
276281
@@ -288,7 +293,7 @@ a#formbuilder
288293
289294 * Explicitly declare the type of the `heroForm` property to be `FormGroup`; you'll initialize it later.
290295 * Inject a `FormBuilder` into the constructor.
291- * Add a new `createForm` method that uses the `FormBuilder` to define the `heroForm`.
296+ * Add a new method that uses the `FormBuilder` to define the `heroForm`; call it `createForm `.
292297 * Call `createForm` in the constructor.
293298
294299 The revised `HeroDetailComponent` looks like this:
@@ -326,12 +331,13 @@ a#formbuilder
326331.l-main-section
327332a#grouping
328333:marked
329- ### Group FormControls
334+ ### Nested FormGroups
330335
331336 This form is getting big and unwieldy. You can group some of the related `FormControls`
332- into another `FormGroup`. The `street`, `city`, `state`, and `zip` are properties
337+ into a nested `FormGroup`. The `street`, `city`, `state`, and `zip` are properties
333338 that would make a good _address_ `FormGroup`.
334- Grouping in this way allows you to mirror the hierarchical structure of the data model
339+ Nesting groups and controls in this way allows you to
340+ mirror the hierarchical structure of the data model
335341 and helps track validation and state for related sets of controls.
336342
337343 You used the `FormBuilder` to create one `FormGroup` in this component called `heroForm`.
@@ -403,7 +409,7 @@ table(width="100%")
403409 td <code >myControl.status</code >
404410 td
405411 :marked
406- whether the `FormControl` is `valid`,
412+ the validity of a `FormControl`. Possible values: `valid`,
407413 `invalid`, `pending`, or `disabled`.
408414 tr
409415 td <code >myControl.pristine</code >
@@ -446,9 +452,6 @@ a#data-model-form-model
446452
447453 2. User changes flow from the DOM elements to the _form model_, not to the _data model_.
448454 The form controls never update the _data model_.
449- In the reactive paradigm, the data model is presumed to be _immutable_
450- and it's your responsibility to preserve that immutability constraint.
451- Kara, Deborah suggested running this by you. Could you confirm that this is the case?
452455
453456 The _form_ and _data_ model structures need not match exactly.
454457 You often present a subset of the _data model_ on a particular screen.
@@ -482,7 +485,9 @@ a#data-model-form-model
482485a#set-data
483486:marked
484487 ## Populate the form model with _setValue_ and _patchValue_
485- You can initialize control values in a `FormGroup` using `setValue` or `patchValue`.
488+ Previously you created a control and initialized its value at the same time.
489+ You can also initialize or reset the values _later_ with the
490+ `setValue` and `patchValue` methods.
486491
487492 ### _setValue_
488493 With **`setValue`**, you assign _every_ form control value _at once_
@@ -491,9 +496,13 @@ a#set-data
491496+ makeExample('reactive-forms/ts/app/hero-detail-versions.component.ts' , 'set-value' ,'app/hero-detail.component.ts (excerpt)' )( format ="." )
492497:marked
493498 The `setValue` method checks the data object thoroughly before assigning any form control values.
494- It rejects a data object that doesn't match the `FormGroup` structure.
495- It rejects a data object if it is missing values for any control in the group.
496- It does return helpful errors.
499+
500+ - It rejects a data object that doesn't match the `FormGroup` structure.
501+ - It rejects a data object if it is missing values for any control in the group.
502+ - It returns helpful error messages.
503+
504+ If you have a typo or nested controls incorrectly, `setValue` will catch
505+ the error and report it clearly. `patchValue` will fail silently.
497506
498507 Notice that you can _almost_ use the entire `hero` as the argument to `setValue`
499508 because its shape is similar to the component's `FormGroup` structure.
@@ -512,7 +521,8 @@ a#set-data
512521
513522:marked
514523 With **`patchValue`** you have more flexibility to cope with wildly divergent data and form models.
515- But unlike `setValue`, `patchValue` cannot check for missing control values and does not return errors.
524+ But unlike `setValue`, `patchValue` cannot check for missing control
525+ values and does not throw helpful errors.
516526
517527 ### When to set form model values (_ngOnChanges_)
518528
@@ -654,7 +664,7 @@ a#form-array
654664 The `HeroDetailComponent` should be able to display, add, and remove items from the _secretLairs_ `FormArray`.
655665
656666 Use the `FormGroup.get` method to acquire a reference to that `FormArray`.
657- Wrap the expression in a `secretLairs` convenience property for clairity and re-use.
667+ Wrap the expression in a `secretLairs` convenience property for clarity and re-use.
658668+ makeExample('reactive-forms/ts/app/hero-detail-versions.component.ts' , 'get-secret-lairs' ,'app/hero-detail.component.ts (secretLayers property)' )( format ="." )
659669
660670:marked
@@ -675,7 +685,7 @@ a#form-array
675685 1. The source of the repeated items is the `FormArray.controls`, not the `FormArray` itself.
676686 Each control is an _address_ `FormGroup`, exactly what the previous (now repeated) template HTML expected.
677687
678- 1. Each repeated `FormGroup` needs a unique `FormGroupName ` which must be the index of the `FormGroup` in the `FormArray`.
688+ 1. Each repeated `FormGroup` needs a unique `formGroupName ` which must be the index of the `FormGroup` in the `FormArray`.
679689 You'll re-use that index to compose a unique label for each address.
680690
681691 Here's the skeleton for the _secret lairs_ section of the HTML template:
@@ -724,9 +734,9 @@ figure.image-display
724734 For extra credit, write a `removeLair` method and wire it to a button on the repeating address HTML.
725735
726736.l-main-section
727- a#watch -control
737+ a#observe -control
728738:marked
729- ## Watch control changes
739+ ## Observe control changes
730740
731741 Angular calls `ngOnChanges` when the user picks a hero in the parent `HeroListComponent`.
732742 Picking a hero changes the `HeroDetailComponent.hero` input property.
0 commit comments