diff --git a/aio/content/examples/forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts b/aio/content/examples/forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts index 5d74a1a8da..5b676c08b8 100644 --- a/aio/content/examples/forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts +++ b/aio/content/examples/forms-overview/src/app/reactive/favorite-color/favorite-color.component.spec.ts @@ -34,13 +34,13 @@ describe('Favorite Color Component', () => { input.value = 'Red'; input.dispatchEvent(event); - expect(fixture.componentInstance.favoriteColor.value).toEqual('Red'); + expect(fixture.componentInstance.favoriteColorControl.value).toEqual('Red'); }); // #enddocregion view-to-model // #docregion model-to-view it('should update the value in the control', () => { - component.favoriteColor.setValue('Blue'); + component.favoriteColorControl.setValue('Blue'); const input = fixture.nativeElement.querySelector('input'); diff --git a/aio/content/examples/forms-overview/src/app/reactive/favorite-color/favorite-color.component.ts b/aio/content/examples/forms-overview/src/app/reactive/favorite-color/favorite-color.component.ts index 560c8a0785..25e901f6e4 100644 --- a/aio/content/examples/forms-overview/src/app/reactive/favorite-color/favorite-color.component.ts +++ b/aio/content/examples/forms-overview/src/app/reactive/favorite-color/favorite-color.component.ts @@ -1,19 +1,13 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'app-reactive-favorite-color', template: ` - Favorite Color: + Favorite Color: `, styles: [] }) -export class FavoriteColorComponent implements OnInit { - favoriteColor = new FormControl(''); - - constructor() { } - - ngOnInit() { - } - +export class FavoriteColorComponent { + favoriteColorControl = new FormControl(''); } diff --git a/aio/content/examples/forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts b/aio/content/examples/forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts index bf7c5e3e0b..60e1830b4d 100644 --- a/aio/content/examples/forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts +++ b/aio/content/examples/forms-overview/src/app/template/favorite-color/favorite-color.component.spec.ts @@ -48,7 +48,7 @@ describe('FavoriteColorComponent', () => { input.value = 'Red'; input.dispatchEvent(event); - tick(); + fixture.detectChanges(); expect(component.favoriteColor).toEqual('Red'); })); diff --git a/aio/content/examples/forms-overview/src/app/template/favorite-color/favorite-color.component.ts b/aio/content/examples/forms-overview/src/app/template/favorite-color/favorite-color.component.ts index ae9aec840b..b5abdffcff 100644 --- a/aio/content/examples/forms-overview/src/app/template/favorite-color/favorite-color.component.ts +++ b/aio/content/examples/forms-overview/src/app/template/favorite-color/favorite-color.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; @Component({ selector: 'app-template-favorite-color', @@ -7,12 +7,6 @@ import { Component, OnInit } from '@angular/core'; `, styles: [] }) -export class FavoriteColorComponent implements OnInit { +export class FavoriteColorComponent { favoriteColor = ''; - - constructor() { } - - ngOnInit() { - } - } diff --git a/aio/content/guide/forms-overview.md b/aio/content/guide/forms-overview.md index d8e9000871..7b99d3b6d0 100644 --- a/aio/content/guide/forms-overview.md +++ b/aio/content/guide/forms-overview.md @@ -34,7 +34,7 @@ Both reactive and template-driven forms share underlying building blocks. - A `FormControl` instance that tracks the value and validation status of an individual form control. - A `FormGroup` instance that tracks the same values and statuses for a collection of form controls. - A `FormArray` instance that tracks the same values and statues for an array of form controls. -- A `ControlValueAccessor` that creates a bridge between Angular form controls and native DOM elements. +- A `ControlValueAccessor` that creates a bridge between Angular `FormControl` instances and native DOM elements. How these control instances are created and managed with reactive and template-driven forms is introduced in the [form model](#the-form-model) section below and detailed further in the [data flow section](#data-flow-in-forms) of this guide. @@ -67,7 +67,7 @@ Here is a component with an input field for a single control implemented using r -The diagrams below shows how the data flows for an input with reactive forms. +The diagrams below show how the data flows for an input with reactive forms.
Reactive forms view to model data flow @@ -75,8 +75,9 @@ The diagrams below shows how the data flows for an input with reactive forms. From the view-to-model: +1. The end user types a value into the input element. 1. The form input element emits an input event with the latest value. -1. The control value accessor on the form input element immediately relays the new value to the `FormControl` instance, which then emits the value through the valueChanges observable. +1. The control value accessor on the form input element immediately relays the new value to the `FormControl` instance, which then emits the value through the `valueChanges` observable.
Reactive forms model to view data flow @@ -84,8 +85,8 @@ From the view-to-model: From the model-to-view: -1. The form control instance sets the latest value and emits the latest value through the `valueChanges` observable. -1. The control value accessor on the form input element is updates the element with the latest value. +1. The `favoriteColorControl.setValue()` method is called, which updates the `FormControl` value and emits the latest value through the `valueChanges` observable. +1. The control value accessor on the form input element updates the element with the latest value. ### Data flow in template-driven forms @@ -94,7 +95,7 @@ Here is the same component with an input field for a single control implemented -The diagrams below shows how the data flows for an input with template-driven forms. +The diagrams below show how the data flows for an input with template-driven forms.
Template-driven forms view to model data flow @@ -102,10 +103,12 @@ The diagrams below shows how the data flows for an input with template-driven fo From the view-to-model: -1. The form input element emits an input event with the latest value. -1. The control value accessor uses the `NgModel` directive to update its model, queues an async task to set the value for the internal form control instance. -1. After the change detection cycle completes, the task to set the form control instance value is called, when then emits the latest value through the `valueChanges` observable. -1. The `ngModelChange` event fires on the `NgModel` directive, which then updates the `favoriteColor` value in the component. +1. The end user types "Blue" into the input element. +1. The input element emits an "input" event with the value "Blue". +1. The control value accessor attached to the input triggers the `setValue()` method on the `FormControl` instance, which emits that value through the `valueChanges` observable. +1. The control value accessor also calls the `NgModel.viewToModel()` method which emits an `ngModelChange` event. +1. Because the component template uses two-way data binding for the `favoriteColor`, the `favoriteColor` property in the component +is updated to the value emitted by the `ngModelChange` event ("Blue").
Template-driven forms model to view data flow @@ -114,8 +117,8 @@ From the view-to-model: From the model-to-view: 1. The `favoriteColor` value is updated in the component. -1. Change detection calls the `ngOnChanges` method on the `NgModel` directive instance, updates the `NgModel` instance model value, and queues an async task to set the value for the internal form control instance. -1. After the change detection cycle completes, the task to set the form control instance value is called, when then emits the latest value through the `valueChanges` observable. +1. Change detection calls the `ngOnChanges` method on the `NgModel` directive instance, updates the `NgModel` instance model value, and queues an async task to set the value for the internal `FormControl` instance. +1. On the next tick, the task to set the `FormControl` instance value is executed, when then emits the latest value through the `valueChanges` observable. 1. The control value accessor updates the form input element in the view with the latest `favoriteColor` value. ## Form validation @@ -161,7 +164,7 @@ The following test validates the view-to-model data flow: 1. Query the view for the form input element, and create a custom input event for the test. 1. Set the new value for the input is set to *Red*, and dispatch the input event on the form input element. -1. Use the `tick()` method to simulate passage of time within the `fakeAsync()` task. +1. Run change detection through the test fixture. 1. Assert that the component `favoriteColor` property value matches the value from the input. The following test validates the model-to-view data flow: