New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs: add forms overview guide #25663
Conversation
You can preview e22d60a at https://pr25663-e22d60a.ngbuilds.io/. |
aio/content/guide/forms-overview.md
Outdated
|
||
## Forms data flows | ||
|
||
When building forms in Angular, its important to be able understand how the the framework handles data flows from user input to the form and changes from code. Reactive and template-driven follow two different strategies when handling these scenarios. Using a simple component with a single input field, we can illustrate how changes are handled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its -> it's?
aio/content/guide/forms-overview.md
Outdated
|
||
```typescript | ||
@Component({ | ||
template: `Name: <input type="text" [formControl]="name"/> ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current convention in doc seems to be <input>
rather than <input/>
. (Another case below)
aio/content/guide/forms-overview.md
Outdated
|
||
Let’s look at how the data flows for an input with reactive forms. | ||
|
||
**Diagram of Input Event flow For Reactive Forms** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flow For -> Flow for? (Another case below)
aio/content/guide/forms-overview.md
Outdated
template: `Name: <input type="text" [(ngModel)]="name"/>` | ||
}) | ||
export class TemplateNameComponent { | ||
name = ‘’; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the ASCII quote.
aio/content/guide/forms-overview.md
Outdated
|
||
**Diagram of Input Event flow For Reactive Forms** | ||
|
||
Template-driven forms are less explicit in that the source of truth for is the directives in the template. Directives are necessary to bind the model to the component class. You no longer have direct control of the form model. Template-driven forms use directives such as NgModel and NgModelGroup to create the form control or group instances and manage their lifecycle within the change detection cycle. This abstraction promotes simplicity over structure. Because template-driven forms are dependent on the UI, the change detection process must complete its cycle where it checks for values changes, queues a task for the value to be updated, and performs a tick before the source of truth is correct. The process happens asynchronously to prevent errors from occuring with values changing during the change detection cycle and introduces unpredictability for querying the source of truth. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NgModel should be in backticks?
You can preview 0388215 at https://pr25663-0388215.ngbuilds.io/. |
packages/forms/PACKAGE.md
Outdated
Angular forms allow you to: | ||
|
||
* Capture the current value and validation status of a form | ||
* Track and listen changes to the form's data model |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
listen for changes
...also, I believe Google style calls for periods on list items
packages/forms/PACKAGE.md
Outdated
|
||
* **Reactive** using existing instances of a `FormControl` or `FormGroup` to build a form model. This form | ||
model is synced with form input elements through directives to track and communicate changes back to the form model. Changes | ||
to the value and status of the controls as provided as observables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are provided
packages/forms/PACKAGE.md
Outdated
|
||
You can build forms in one of two ways: | ||
|
||
* **Reactive** using existing instances of a `FormControl` or `FormGroup` to build a form model. This form |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reactive forms use ...
(bold doesn't render properly)
packages/forms/PACKAGE.md
Outdated
* **Reactive** using existing instances of a `FormControl` or `FormGroup` to build a form model. This form | ||
model is synced with form input elements through directives to track and communicate changes back to the form model. Changes | ||
to the value and status of the controls as provided as observables. | ||
* **Template-driven** using directives such as `NgModel` and `NgModelGroup` that provide two-way data binding to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Template-driven forms use ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Started copy edit, but too awkward in git. Leaving it for Sarah - just reading it now.
# Forms in Angular | ||
|
||
Handling user input with forms is the cornerstone of many common applications. You use forms to log in to a page, updating a profile, entering sensitive information, and many other data-entry tasks. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make parallel:
...to log in, to update a profile, to enter sensitive information, and to perform many other...
0388215
to
b819bf6
Compare
You can preview b819bf6 at https://pr25663-b819bf6.ngbuilds.io/. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great. Some comments below. I think it will be a bit easier to review once the diagrams are in.
aio/content/guide/forms-overview.md
Outdated
|
||
Handling user input with forms is the cornerstone of many common applications. You use forms to log in, to update a profile, to enter sensitive information, and to perform many other data-entry tasks. | ||
|
||
Angular provides two different approaches to handling user input through forms: Reactive and template-driven. Each set of forms promote a distinct way of processing forms and offers different advantages. The sections below provide a comparison of the two approaches and when each one is applicable. There are many different factors that influence your decision on which approach works best for your situation. Whether you’re using reactive or template driven forms, these concepts are key to understanding the mechanisms underneath each solution. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: capitalization should be consistent
...input through forms: reactive and template-driven.
Nit: hyphenation should be consistent
Whether you're using reactive or template-driven forms, these...
Nit: I think we can remove the second-to-last sentence and not lose any of the meaning.
aio/content/guide/forms-overview.md
Outdated
In general: | ||
|
||
* **Reactive forms** are more robust: they are more scalable, reusable, and testable. If forms are a key part of your application, use reactive forms. | ||
* **Template-driven forms** are useful for adding a simple form to an app, such as a single email list signup form. They are easy to add to an app, but they do not scale as well as reactive forms. If you have very simple form with only static data, use template-driven forms. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: missing an "a"
If you have a very simple form with...
Also thinking we should clarify "static data", so people don't think we mean a form where "values don't change" (which isn't really a form anymore) or "controls aren't being added/removed" (this is fine in TD forms as long as you use ngIf
). I think we mean something like "with basic logic that can be managed solely in the template" - because it gets confusing handling template-driven directives in the component class.
Also do we want to mention data flow somewhere here? If you are using reactive patterns, you probably don't want to use template-driven. Or maybe this is too early? What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its ok to mention here as a quick decision point. I updated the text to be:
- Reactive forms are more robust: they are more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.
aio/content/guide/forms-overview.md
Outdated
|
||
## A common foundation | ||
|
||
Both reactive and template-driven forms share underlying building blocks, the `FormControl`, `FormGroup` and the `ControlValueAccessor` interface. A `FormControl` instance tracks the value and validation status of an individual form control element. A `FormGroup` instance tracks the same values and statuses for a collection of form controls. How these control instances are created and managed with reactive and template-driven forms will be discussed later in this guide. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the three main building blocks here should be FormControl
, FormGroup
, and FormArray
(with a sentence describing FormArray
too). Value accessors are common to both modules but I wouldn't put them in the same list.
...share underlying building blocks: the
FormControl
,FormGroup
, andFormArray
.
Maybe we can remove the section head for value accessors below and discuss them in the next paragraph?
aio/content/guide/forms-overview.md
Outdated
|
||
## Control value accessors | ||
|
||
Control value accessors define a bridge between Angular forms and native DOM elements. The `ControlValueAccessor` interface defines methods for interacting with native elements including: reading from and writing values to them, providing callback functions to listen for value changes, when they are touched, and or enabled or disabled. A [default control value accessor](api/forms/DefaultValueAccessor) is attached to every input element when using either forms modules in Angular. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: enabling/disabling isn't a callback
reading from and writing values to them, disabling or enabling their elements, and providing callback functions for when the control's value changes in the UI or it becomes touched.
We probably shouldn't call out DefaultValueAccessor
as attached to every input element since it only applies to text fields that don't have custom value accessors defined. Maybe change to:
A built-in value accessor is attached to every form field when using either forms modules in Angular (example: DefaultValueAccessor), unless a custom value accessor has been activated on that field.
aio/content/guide/forms-overview.md
Outdated
|
||
## Forms data flows | ||
|
||
When building forms in Angular, it's important to be able understand how the the framework handles data flows from user input to the form and changes from code. Reactive and template-driven follow two different strategies when handling these scenarios. Using a simple component with a single input field, we can illustrate how changes are handled. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... it's important to understand how the framework handles data flowing from the user or from programmatic changes.
aio/content/guide/forms-overview.md
Outdated
} | ||
``` | ||
|
||
**Diagram of Input Event Flow For Reactive Forms** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Diagram?
aio/content/guide/forms-overview.md
Outdated
|
||
**Diagram of Input Event Flow For Reactive Forms** | ||
|
||
Template-driven forms are less explicit in that the source of truth for is the directives in the template. Directives are necessary to bind the model to the component class. You no longer have direct control of the form model. Template-driven forms use directives such as `NgModel` and `NgModelGroup` to create the form control or group instances and manage their lifecycle within the change detection cycle. This abstraction promotes simplicity over structure. Because template-driven forms are dependent on the UI, the change detection process must complete its cycle where it checks for values changes, queues a task for the value to be updated, and performs a tick before the source of truth is correct. The process happens asynchronously to prevent errors from occuring with values changing during the change detection cycle and introduces unpredictability for querying the source of truth. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In template-driven forms, the source of truth is the template, so developers create their desired form through the placement of template-driven directives like
NgModel
andNgModelGroup
. The directives then create theFormControl
orFormGroup
instances that make up the form model, link them with form elements through a value accessor, and manage them within the constraints of the template's change detection cycle.
This abstraction promotes simplicity over structure. It is less explicit, but you no longer have direct control over the form model. It is simple to add directives, but because these directives are dependent on the UI, they must work around the change detection cycle. Programmatic value changes are registered during change detection (as they occur through an
@Input
to a directive), so it's not possible to update the value and validity immediately because it may affect elements that have already been checked in that view (e.g. the parent form). For this reason, value changes are delayed until the next tick, which allows change detection to complete and a new change detection process to be triggered with the updated value. In other words, the process happens asynchronously and introduces unpredictability for querying the source of truth.
aio/content/guide/forms-overview.md
Outdated
|
||
## Custom validation and testing | ||
|
||
Validation is an integral part of managing any set of forms. Whether you’re checking for required fields or querying an external API for an existing username, Angular provides a set of built-in validators as well as the ability to create custom validators. With reactive forms, creating custom validators are achieved functions that receives control to validate and returns a result immediately. Because template-driven forms are tied to directives, custom validator directives must be created to wrap a validator function in order to use it in a template. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With reactive forms, custom validators are functions that receive a control to value to validate.
aio/content/guide/forms-overview.md
Outdated
|
||
For more on form validation, visit the [Form Validation](guide/form-validation) guide. | ||
|
||
Testing also plays a large part in complex applications and an easier testing strategy is always welcomed. Reactive forms provide an easy testing strategy to due to synchronous access to the form and data models, where controls and data can be queried and manipulated easily through the control without rendering a view. Template-driven forms are asynchronous, which complicates complex testing scenarios. It involves more detailed knowledge of the change detection process and how directives run on each cycle to ensure elements can be queried at the correct time. In order to access the underlying controls with template-driven forms, you must use `ViewChild` to access the `NgForm` and wait for the appropiate lifecycle hooks to finish before extracting any values, testing its validity or changing its value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove the part about ViewChild
because I'd rather not encourage that:
In order to access the underlying controls with template-driven forms, you must wait for the appropriate lifecycle hooks to finish before extracting any values, testing its validity or changing its value.
I think the testing section might benefit from an example comparing a simple test.
aio/content/guide/forms-overview.md
Outdated
</td> | ||
|
||
<td> | ||
Immutable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm can you explain what you mean by mutable in TD?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a section above scalability
Mutability
How changes are tracked plays a role in the efficiency of your application. Reactive forms keep the data model pure by providing it as an immutable data structure. Each time the a change is triggered on the data model, a new data model is returned rather than updating the data model directly. This is more efficient, giving you the ability track unique changes to the data model. It also follows reactive patterns that integrate with observable operators to map and transform data. Template-driven forms rely on mutability with two-way data binding to update the data model in the component as changes are made in the template.
b819bf6
to
0d05573
Compare
You can preview 0d05573 at https://pr25663-0d05573.ngbuilds.io/. |
0d05573
to
210d1e3
Compare
You can preview 210d1e3 at https://pr25663-210d1e3.ngbuilds.io/. |
aio/content/guide/forms-overview.md
Outdated
|
||
**Diagram of Input Event Flow For Reactive Forms** | ||
|
||
### Data flow in template-driven forms |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this header is too high? It comes before the reactive forms explanation.
You can preview 8542715 at https://pr25663-8542715.ngbuilds.io/. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
What is the new behavior?
Does this PR introduce a breaking change?
Other information
Adds Forms Overview page to Forms section. Reorganizes forms guides in nav also.