@@ -128,11 +128,13 @@ Then you'll learn about the [Angular form classes](guide/reactive-forms#essentia
## Setup
Follow the steps in the [_Setup_ guide ](guide/setup "Setup guide" )
for creating a new project folder (perhaps called `reactive-forms` )
based on the _ QuickStart seed _ .
Create a new project named <code>angular-reactive-forms</code>:
<code-example language="sh" class="code-shell">
ng new angular-reactive-forms
</code-example>
{@a data-model}
@@ -140,15 +142,21 @@ based on the _QuickStart seed_.
## Create a data model
The focus of this guide is a reactive forms component that edits a hero.
You'll need a `hero` class and some hero data.
Create a new `data-model.ts` file in the `app` directory and copy the content below into it.
Using the CLI, generate a new class named `data-model` :
<code-example language="sh" class="code-shell">
ng generate class data-model
</code-example>
And copy the content below:
<code-example path="reactive-forms/src/app/data-model.ts" title="src/app/data-model.ts" linenums="false">
</code-example>
The file exports two classes and two constants. The `Address`
and `Hero` classes define the application _ data model _ .
The `heroes` and `states` constants supply the test data.
@@ -159,32 +167,26 @@ The `heroes` and `states` constants supply the test data.
## Create a _reactive forms_ component
Make a new file called
`hero-detail.component.ts` in the `app` directory and import these symbols:
Generate a new component named `HeroDetail` :
<code-example path="reactive-forms/src/app/hero-detail-1.component.ts" region="imports" title="src/app/hero-detail.component.ts" linenums="false ">
<code-example language="sh" class="code-shell ">
ng generate component HeroDetail
</code-example>
And import:
Now enter the `@Component` decorator that specifies the `HeroDetailComponent` metadata:
<code-example path="reactive-forms/src/app/hero-detail.component.ts" region="metadata" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail-1.component.ts" region="import" title="src/app/hero-detail/hero-detail.component.ts" linenums="false">
</code-example>
Next, create an exported `HeroDetailComponent` class with a `FormControl` .
Next, update the `HeroDetailComponent` class with a `FormControl` .
`FormControl` is a directive that allows you to create and manage
a `FormControl` instance directly.
<code-example path="reactive-forms/src/app/hero-detail-1.component.ts" region="v1" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail-1.component.ts" region="v1" title="src/app/hero-detail/hero-detail.component.ts (excerpt)" linenums="false">
</code-example>
@@ -218,10 +220,10 @@ read the [Form Validation](guide/form-validation) guide.
## Create the template
Now cre ate the component's template, `src/app/hero-detail.component.html` , with the following markup.
Now upd ate the component's template, with the following markup.
<code-example path="reactive-forms/src/app/hero-detail-1.component.html" region="simple-control" title="src/app/hero-detail.component.html" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -1.component.html" region="simple-control" title="src/app/hero-detail/hero-detail .component.html" linenums="false">
</code-example>
@@ -255,13 +257,11 @@ It _styles_ the form but in no way impacts the logic of the form.
The HeroDetailComponent template uses `formControlName`
directive from the `ReactiveFormsModule` .
In this sample, you declare the `HeroDetailComponent` in the `A ppM odule` .
Therefore, do the following three things in `app.module.ts` :
Do the following two things in `a pp.m odule.ts ` :
1. Use a JavaScript `import` statement to access
the `ReactiveFormsModule` and the `HeroDetailComponent` .
the `ReactiveFormsModule` .
1. Add `ReactiveFormsModule` to the `AppModule` 's `imports` list.
1. Add `HeroDetailComponent` to the declarations array.
<code-example path="reactive-forms/src/app/app.module.ts" region="v1" title="src/app/app.module.ts (excerpt)" linenums="false">
@@ -277,7 +277,7 @@ the `ReactiveFormsModule` and the `HeroDetailComponent`.
## Display the _HeroDetailComponent_
Revise the `AppComponent` template so it displays the `HeroDetailComponent` .
<code-example path="reactive-forms/src/app/app.component.1.ts " title="src/app/app.component.ts " linenums="false">
<code-example path="reactive-forms/src/app/app.component.1.html " title="src/app/app.component.html " linenums="false">
</code-example>
@@ -312,10 +312,10 @@ You'll learn more about these classes as you work through this guide.
### Style the app
You used bootstrap CSS classes in the template HTML of both the `AppComponent` and the `HeroDetailComponent` .
Add the `bootstrap` _ CSS stylesheet _ to the head of `index.html ` :
Add the `bootstrap` _ CSS stylesheet _ to the head of `styles.css ` :
<code-example path="reactive-forms/src/index.html" region="bootstrap" title="index.html " linenums="false">
<code-example path="reactive-forms/src/styles.1.css" title="styles.css " linenums="false">
</code-example>
@@ -340,7 +340,7 @@ This is simple to do. To add a `FormGroup`, add it to the imports section
of `hero-detail.component.ts` :
<code-example path="reactive-forms/src/app/hero-detail-2.component.ts" region="imports" title="src/app/hero-detail.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -2.component.ts" region="imports" title="src/app/hero-detail/hero-detail .component.ts" linenums="false">
</code-example>
@@ -349,7 +349,7 @@ of `hero-detail.component.ts`:
In the class, wrap the `FormControl` in a `FormGroup` called `heroForm` as follows:
<code-example path="reactive-forms/src/app/hero-detail-2.component.ts" region="v2" title="src/app/hero-detail.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -2.component.ts" region="v2" title="src/app/hero-detail/hero-detail .component.ts" linenums="false">
</code-example>
@@ -359,7 +359,7 @@ Now that you've made changes in the class, they need to be reflected in the
template. Update `hero-detail.component.html` by replacing it with the following.
<code-example path="reactive-forms/src/app/hero-detail-2.component.html" region="basic-form" title="src/app/hero-detail.component.html" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -2.component.html" region="basic-form" title="src/app/hero-detail/hero-detail .component.html" linenums="false">
</code-example>
@@ -418,7 +418,7 @@ To see the form model, add the following line after the
closing `form` tag in the `hero-detail.component.html` :
<code-example path="reactive-forms/src/app/hero-detail-3.component.html" region="form-value-json" title="src/app/hero-detail.component.html" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -3.component.html" region="form-value-json" title="src/app/hero-detail/hero-detail .component.html" linenums="false">
</code-example>
@@ -458,7 +458,7 @@ clutter by handling details of control creation for you.
To use `FormBuilder` , you need to import it into `hero-detail.component.ts` :
<code-example path="reactive-forms/src/app/hero-detail-3a.component.ts" region="imports" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -3a.component.ts" region="imports" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -474,7 +474,7 @@ by following this plan:
The revised `HeroDetailComponent` looks like this:
<code-example path="reactive-forms/src/app/hero-detail-3a.component.ts" region="v3a" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -3a.component.ts" region="v3a" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -497,7 +497,7 @@ demonstrates the simplicity of using `Validators.required` in reactive forms.
First, import the `Validators` symbol.
<code-example path="reactive-forms/src/app/hero-detail-3.component.ts" region="imports" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -3.component.ts" region="imports" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -509,7 +509,7 @@ The first item is the initial value for `name`;
the second is the required validator, `Validators.required` .
<code-example path="reactive-forms/src/app/hero-detail-3.component.ts" region="required" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -3.component.ts" region="required" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -529,7 +529,7 @@ Configuring validation is harder in template-driven forms where you must wrap va
Update the diagnostic message at the bottom of the template to display the form's validity status.
<code-example path="reactive-forms/src/app/hero-detail-3.component.html" region="form-value-json" title="src/app/hero-detail.component.html (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -3.component.html" region="form-value-json" title="src/app/hero-detail/hero-detail .component.html (excerpt)" linenums="false">
</code-example>
@@ -564,7 +564,7 @@ A hero has an address, a super power and sometimes a sidekick too.
The address has a state property. The user will select a state with a `<select>` box and you'll populate
the `<option>` elements with states. So import `states` from `data-model.ts` .
<code-example path="reactive-forms/src/app/hero-detail-4.component.ts" region="imports" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -4.component.ts" region="imports" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -573,7 +573,7 @@ the `<option>` elements with states. So import `states` from `data-model.ts`.
Declare the `states` property and add some address `FormControls` to the `heroForm` as follows.
<code-example path="reactive-forms/src/app/hero-detail-4.component.ts" region="v4" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -4.component.ts" region="v4" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -583,7 +583,7 @@ Then add corresponding markup in `hero-detail.component.html`
within the `form` element.
<code-example path="reactive-forms/src/app/hero-detail-4.component.html" title="src/app/hero-detail.component.html" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -4.component.html" title="src/app/hero-detail/hero-detail .component.html" linenums="false">
</code-example>
@@ -640,7 +640,7 @@ Let that be the parent `FormGroup`.
Use `FormBuilder` again to create a child `FormGroup` that encapsulates the address controls;
assign the result to a new `address` property of the parent `FormGroup` .
<code-example path="reactive-forms/src/app/hero-detail-5.component.ts" region="v5" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -5.component.ts" region="v5" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -657,7 +657,7 @@ To make this change visually obvious, slip in an `<h4>` header near the top with
The new _ address _ HTML looks like this:
<code-example path="reactive-forms/src/app/hero-detail-5.component.html" region="add-group" title="src/app/hero-detail.component.html (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -5.component.html" region="add-group" title="src/app/hero-detail/hero-detail .component.html (excerpt)" linenums="false">
</code-example>
@@ -691,7 +691,7 @@ page by adding the following to the template,
immediately after the `{{form.value | json}}` interpolation as follows:
<code-example path="reactive-forms/src/app/hero-detail-5.component.html" region="inspect-value" title="src/app/hero-detail.component.html" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -5.component.html" region="inspect-value" title="src/app/hero-detail/hero-detail .component.html" linenums="false">
</code-example>
@@ -700,7 +700,7 @@ immediately after the `{{form.value | json}}` interpolation as follows:
To get the state of a `FormControl` that’ s inside a `FormGroup` , use dot notation to path to the control.
<code-example path="reactive-forms/src/app/hero-detail-5.component.html" region="inspect-child-control" title="src/app/hero-detail.component.html" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -5.component.html" region="inspect-child-control" title="src/app/hero-detail/hero-detail .component.html" linenums="false">
</code-example>
@@ -851,7 +851,7 @@ Recall the definition of `Hero` in `data-model.ts`:
Here, again, is the component's `FormGroup` definition.
<code-example path="reactive-forms/src/app/hero-detail-6.component.ts" region="hero-form-model" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -6.component.ts" region="hero-form-model" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -870,7 +870,7 @@ to the _form model_ with the `patchValue` and `setValue` methods.
Take a moment to refactor the _ address _ `FormGroup` definition for brevity and clarity as follows:
<code-example path="reactive-forms/src/app/hero-detail-7.component.ts" region="address-form-group" title="src/app/hero-detail-7.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -7.component.ts" region="address-form-group" title="src/app/hero-detail/hero-detail -7.component.ts" linenums="false">
</code-example>
@@ -878,7 +878,7 @@ Take a moment to refactor the _address_ `FormGroup` definition for brevity and c
Also be sure to update the import from `data-model` so you can reference the `Hero` and `Address` classes:
<code-example path="reactive-forms/src/app/hero-detail-7.component.ts" region="import-address" title="src/app/hero-detail-7.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -7.component.ts" region="import-address" title="src/app/hero-detail/hero-detail -7.component.ts" linenums="false">
</code-example>
@@ -898,7 +898,7 @@ With **`setValue`**, you assign _every_ form control value _at once_
by passing in a data object whose properties exactly match the _ form model _ behind the `FormGroup` .
<code-example path="reactive-forms/src/app/hero-detail-7.component.ts" region="set-value" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -7.component.ts" region="set-value" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -920,7 +920,7 @@ because its shape is similar to the component's `FormGroup` structure.
You can only show the hero's first address and you must account for the possibility that the `hero` has no addresses at all.
This explains the conditional setting of the `address` property in the data object argument:
<code-example path="reactive-forms/src/app/hero-detail-7.component.ts" region="set-value-address" title="src/app/hero-detail-7.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -7.component.ts" region="set-value-address" title="src/app/hero-detail/hero-detail -7.component.ts" linenums="false">
</code-example>
@@ -932,7 +932,7 @@ by supplying an object of key/value pairs for just the controls of interest.
This example sets only the form's `name` control.
<code-example path="reactive-forms/src/app/hero-detail-6.component.ts" region="patch-value" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -6.component.ts" region="patch-value" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -953,7 +953,7 @@ When the user clicks on a hero, the list component passes the selected hero into
by binding to its `hero` input property.
<code-example path="reactive-forms/src/app/hero-list.component.1.html" title="hero-list.component.html (simplified)" linenums="false">
<code-example path="reactive-forms/src/app/hero-list/hero-list .component.1.html" title="hero-list.component.html (simplified)" linenums="false">
</code-example>
@@ -968,7 +968,7 @@ as the following steps demonstrate.
First, import the `OnChanges` and `Input` symbols in `hero-detail.component.ts` .
<code-example path="reactive-forms/src/app/hero-detail-6.component.ts" region="import-input" title="src/app/hero-detail.component.ts (core imports)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -6.component.ts" region="import-input" title="src/app/hero-detail/hero-detail .component.ts (core imports)" linenums="false">
</code-example>
@@ -976,7 +976,7 @@ First, import the `OnChanges` and `Input` symbols in `hero-detail.component.ts`.
Add the `hero` input property.
<code-example path="reactive-forms/src/app/hero-detail-6.component.ts" region="hero" title="src/app/hero-detail-6.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -6.component.ts" region="hero" title="src/app/hero-detail/hero-detail -6.component.ts" linenums="false">
</code-example>
@@ -985,7 +985,7 @@ Add the `hero` input property.
Add the `ngOnChanges` method to the class as follows:
<code-example path="reactive-forms/src/app/hero-detail-7.component.ts" region="ngOnChanges-1" title="src/app/hero-detail.component.ts (ngOnchanges)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -7.component.ts" region="ngOnChanges-1" title="src/app/hero-detail/hero-detail .component.ts (ngOnchanges)" linenums="false">
</code-example>
@@ -998,7 +998,7 @@ control values from the previous hero are cleared and
status flags are restored to the _ pristine _ state.
You could call `reset` at the top of `ngOnChanges` like this.
<code-example path="reactive-forms/src/app/hero-detail-7.component.ts" region="reset" title="src/app/hero-detail-7.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -7.component.ts" region="reset" title="src/app/hero-detail/hero-detail -7.component.ts" linenums="false">
</code-example>
@@ -1008,7 +1008,7 @@ The `reset` method has an optional `state` value so you can reset the flags _and
Internally, `reset` passes the argument to `setValue` .
A little refactoring and `ngOnChanges` becomes this:
<code-example path="reactive-forms/src/app/hero-detail-7.component.ts" region="ngOnChanges" title="src/app/hero-detail.component.ts (ngOnchanges - revised)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -7.component.ts" region="ngOnChanges" title="src/app/hero-detail/hero-detail .component.ts (ngOnchanges - revised)" linenums="false">
</code-example>
@@ -1049,7 +1049,7 @@ The techniques involved are covered elsewhere in the documentation, including th
[here ](tutorial/toh-pt3 "ToH: Multiple Components" ) and [here ](tutorial/toh-pt4 "ToH: Services" ).
If you're coding along with the steps in this reactive forms tutorial,
cre ate the pertinent files based on the
gener ate the pertinent files based on the
[source code displayed below ](guide/reactive-forms#source-code "Reactive Forms source code" ).
Notice that `hero-list.component.ts` imports `Observable` and `finally` while `hero.service.ts` imports `Observable` , `of` ,
and `delay` from `rxjs` .
@@ -1073,7 +1073,7 @@ An Angular `FormArray` can display an array of _address_ `FormGroups`.
To get access to the `FormArray` class, import it into `hero-detail.component.ts` :
<code-example path="reactive-forms/src/app/hero-detail-8.component.ts" region="imports" title="src/app/hero-detail.component.ts (excerpt)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.ts" region="imports" title="src/app/hero-detail/hero-detail .component.ts (excerpt)" linenums="false">
</code-example>
@@ -1093,7 +1093,7 @@ let the user add or modify addresses (removing addresses is your homework).
You’ ll need to redefine the form model in the `HeroDetailComponent` constructor,
which currently only displays the first hero address in an _ address _ `FormGroup` .
<code-example path="reactive-forms/src/app/hero-detail-7.component.ts" region="address-form-group" title="src/app/hero-detail-7.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -7.component.ts" region="address-form-group" title="src/app/hero-detail/hero-detail -7.component.ts" linenums="false">
</code-example>
@@ -1105,7 +1105,7 @@ From the user's point of view, heroes don't have _addresses_.
_ Addresses _ are for mere mortals. Heroes have _ secret lairs _ !
Replace the _ address _ `FormGroup` definition with a _ secretLairs _ `FormArray` definition:
<code-example path="reactive-forms/src/app/hero-detail-8.component.ts" region="secretLairs-form-array" title="src/app/hero-detail-8.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.ts" region="secretLairs-form-array" title="src/app/hero-detail/hero-detail -8.component.ts" linenums="false">
</code-example>
@@ -1139,7 +1139,7 @@ the parent `HeroListComponent` sets the `HeroDetailComponent.hero` input propert
The following `setAddresses` method replaces the _ secretLairs _ `FormArray` with a new `FormArray` ,
initialized by an array of hero address `FormGroups` .
<code-example path="reactive-forms/src/app/hero-detail-8.component.ts" region="set-addresses" title="src/app/hero-detail-8.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.ts" region="set-addresses" title="src/app/hero-detail/hero-detail -8.component.ts" linenums="false">
</code-example>
@@ -1156,7 +1156,7 @@ The `HeroDetailComponent` should be able to display, add, and remove items from
Use the `FormGroup.get` method to acquire a reference to that `FormArray` .
Wrap the expression in a `secretLairs` convenience property for clarity and re-use.
<code-example path="reactive-forms/src/app/hero-detail-8.component.ts" region="get-secret-lairs" title="src/app/hero-detail.component.ts (secretLayers property)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.ts" region="get-secret-lairs" title="src/app/hero-detail/hero-detail .component.ts (secretLayers property)" linenums="false">
</code-example>
@@ -1184,7 +1184,7 @@ You'll re-use that index to compose a unique label for each address.
Here's the skeleton for the _ secret lairs _ section of the HTML template:
<code-example path="reactive-forms/src/app/hero-detail-8.component.html" region="form-array-skeleton" title="src/app/hero-detail.component.html (*ngFor)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.html" region="form-array-skeleton" title="src/app/hero-detail/hero-detail .component.html (*ngFor)" linenums="false">
</code-example>
@@ -1192,7 +1192,7 @@ Here's the skeleton for the _secret lairs_ section of the HTML template:
Here's the complete template for the _ secret lairs _ section:
<code-example path="reactive-forms/src/app/hero-detail-8.component.html" region="form-array" title="src/app/hero-detail.component.html (excerpt)">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.html" region="form-array" title="src/app/hero-detail/hero-detail .component.html (excerpt)">
</code-example>
@@ -1202,7 +1202,7 @@ Here's the complete template for the _secret lairs_ section:
Add an `addLair` method that gets the _ secretLairs _ `FormArray` and appends a new _ address _ `FormGroup` to it.
<code-example path="reactive-forms/src/app/hero-detail-8.component.ts" region="add-lair" title="src/app/hero-detail.component.ts (addLair method)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.ts" region="add-lair" title="src/app/hero-detail/hero-detail .component.ts (addLair method)" linenums="false">
</code-example>
@@ -1211,7 +1211,7 @@ Add an `addLair` method that gets the _secretLairs_ `FormArray` and appends a ne
Place a button on the form so the user can add a new _ secret lair _ and wire it to the component's `addLair` method.
<code-example path="reactive-forms/src/app/hero-detail-8.component.html" region="add-lair" title="src/app/hero-detail.component.html (addLair button)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.html" region="add-lair" title="src/app/hero-detail/hero-detail .component.html (addLair button)" linenums="false">
</code-example>
@@ -1272,7 +1272,7 @@ You don't need to know much about RxJS `Observable` to monitor form control valu
Add the following method to log changes to the value of the _ name _ `FormControl` .
<code-example path="reactive-forms/src/app/hero-detail.component.ts" region="log-name-change" title="src/app/hero-detail.component.ts (logNameChange)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail .component.ts" region="log-name-change" title="src/app/hero-detail/hero-detail .component.ts (logNameChange)" linenums="false">
</code-example>
@@ -1280,7 +1280,7 @@ Add the following method to log changes to the value of the _name_ `FormControl`
Call it in the constructor, after creating the form.
<code-example path="reactive-forms/src/app/hero-detail-8.component.ts" region="ctor" title="src/app/hero-detail-8.component.ts" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail -8.component.ts" region="ctor" title="src/app/hero-detail/hero-detail -8.component.ts" linenums="false">
</code-example>
@@ -1289,7 +1289,7 @@ Call it in the constructor, after creating the form.
The `logNameChange` method pushes name-change values into a `nameChangeLog` array.
Display that array at the bottom of the component template with this `*ngFor` binding:
<code-example path="reactive-forms/src/app/hero-detail.component.html" region="name-change-log" title="src/app/hero-detail.component.html (Name change log)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail .component.html" region="name-change-log" title="src/app/hero-detail/hero-detail .component.html (Name change log)" linenums="false">
</code-example>
@@ -1328,7 +1328,7 @@ In this sample application, when the user submits the form,
the `HeroDetailComponent` will pass an instance of the hero _ data model _
to a save method on the injected `HeroService` .
<code-example path="reactive-forms/src/app/hero-detail.component.ts" region="on-submit" title="src/app/hero-detail.component.ts (onSubmit)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail .component.ts" region="on-submit" title="src/app/hero-detail/hero-detail .component.ts (onSubmit)" linenums="false">
</code-example>
@@ -1339,7 +1339,7 @@ So you create a new `hero` from a combination of original hero values (the `hero
and deep copies of the changed form model values, using the `prepareSaveHero` helper.
<code-example path="reactive-forms/src/app/hero-detail.component.ts" region="prepare-save-hero" title="src/app/hero-detail.component.ts (prepareSaveHero)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail .component.ts" region="prepare-save-hero" title="src/app/hero-detail/hero-detail .component.ts (prepareSaveHero)" linenums="false">
</code-example>
@@ -1368,7 +1368,7 @@ The user cancels changes and reverts the form to the original state by pressing
Reverting is easy. Simply re-execute the `ngOnChanges` method that built the _ form model _ from the original, unchanged `hero` _ data model _ .
<code-example path="reactive-forms/src/app/hero-detail.component.ts" region="revert" title="src/app/hero-detail.component.ts (revert)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail .component.ts" region="revert" title="src/app/hero-detail/hero-detail .component.ts (revert)" linenums="false">
</code-example>
@@ -1377,7 +1377,7 @@ Reverting is easy. Simply re-execute the `ngOnChanges` method that built the _fo
### Buttons
Add the "Save" and "Revert" buttons near the top of the component's template:
<code-example path="reactive-forms/src/app/hero-detail.component.html" region="buttons" title="src/app/hero-detail.component.html (Save and Revert buttons)" linenums="false">
<code-example path="reactive-forms/src/app/hero-detail/hero-detail .component.html" region="buttons" title="src/app/hero-detail/hero-detail .component.html (Save and Revert buttons)" linenums="false">
</code-example>
@@ -1395,9 +1395,7 @@ Try the <live-example plnkr="final" title="Reactive Forms (final) in Plunker"></
## Conclusion
This page covered:
## Summary
* How to create a reactive form component and its corresponding template.
* How to use `FormBuilder` to simplify coding a reactive form.
@@ -1417,6 +1415,10 @@ The key files of the final version are as follows:
<code-tabs>
<code-pane title="src/app/app.component.html" path="reactive-forms/src/app/app.component.html">
</code-pane>
<code-pane title="src/app/app.component.ts" path="reactive-forms/src/app/app.component.ts">
</code-pane>
@@ -1425,19 +1427,19 @@ The key files of the final version are as follows:
</code-pane>
<code-pane title="src/app/hero-detail.component.ts" path="reactive-forms/src/app/hero-detail.component.ts">
<code-pane title="src/app/hero-detail/hero-detail .component.ts" path="reactive-forms/src/app/hero-detail/hero-detail .component.ts">
</code-pane>
<code-pane title="src/app/hero-detail.component.html" path="reactive-forms/src/app/hero-detail.component.html">
<code-pane title="src/app/hero-detail/hero-detail .component.html" path="reactive-forms/src/app/hero-detail/hero-detail .component.html">
</code-pane>
<code-pane title="src/app/hero-list.component.html" path="reactive-forms/src/app/hero-list.component.html">
<code-pane title="src/app/hero-list/hero-list .component.html" path="reactive-forms/src/app/hero-list/hero-list .component.html">
</code-pane>
<code-pane title="src/app/hero-list.component.ts" path="reactive-forms/src/app/hero-list.component.ts">
<code-pane title="src/app/hero-list/hero-list .component.ts" path="reactive-forms/src/app/hero-list/hero-list .component.ts">
</code-pane>