You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: aio/content/guide/dynamic-form.md
+10-10
Original file line number
Diff line number
Diff line change
@@ -3,15 +3,15 @@
3
3
Many forms, such as questionaires, can be very similar to one another in format and intent.
4
4
To make it faster and easier to generate different versions of such a form,
5
5
you can create a *dynamic form template* based on metadata that describes the business object model.
6
-
You can then use the template to generate new forms automatically, according to changes in the data model.
6
+
Then, use the template to generate new forms automatically, according to changes in the data model.
7
7
8
8
The technique is particularly useful when you have a type of form whose content must
9
9
change frequently to meet rapidly changing business and regulatory requirements.
10
10
A typical use case is a questionaire. You might need to get input from users in different contexts.
11
11
The format and style of the forms a user sees should remain constant, while the actual questions you need to ask vary with the context.
12
12
13
13
In this tutorial you will build a dynamic form that presents a basic questionaire.
14
-
You will build an online application for heroes seeking employment.
14
+
You build an online application for heroes seeking employment.
15
15
The agency is constantly tinkering with the application process, but by using the dynamic form
16
16
you can create the new forms on the fly without changing the application code.
17
17
@@ -81,14 +81,14 @@ The following `QuestionBase` is a base class for a set of controls that can repr
81
81
82
82
From this base, the example derives two new classes, `TextboxQuestion` and `DropdownQuestion`,
83
83
that represent different control types.
84
-
When you create the form template in the next step, you will instantiate these specific question types in order to render the appropriate controls dynamically.
84
+
When you create the form template in the next step, you instantiate these specific question types in order to render the appropriate controls dynamically.
85
85
86
-
* The `TextboxQuestion` control type presents a question and allows users to enter input.
86
+
* The `TextboxQuestion` control type presents a question and lets users enter input.
The `TextboxQuestion` control type will be represented in a form template using an `<input>` element.
91
-
The `type` attribute of the element will be defined based on the `type` field specified in the `options` argument (for example `text`, `email`, `url`).
90
+
The `TextboxQuestion` control type is represented in a form template using an `<input>` element.
91
+
The `type` attribute of the element is defined based on the `type` field specified in the `options` argument (for example `text`, `email`, `url`).
92
92
93
93
* The `DropdownQuestion` control presents a list of choices in a select box.
94
94
@@ -105,7 +105,7 @@ The following `QuestionControlService` collects a set of `FormGroup` instances t
105
105
106
106
## Compose dynamic form contents
107
107
108
-
The dynamic form itself will be represented by a container component, which you will add in a later step.
108
+
The dynamic form itself is represented by a container component, which you add in a later step.
109
109
Each question is represented in the form component's template by an `<app-question>` tag, which matches an instance of `DynamicFormQuestionComponent`.
110
110
111
111
The `DynamicFormQuestionComponent` is responsible for rendering the details of an individual question based on values in the data-bound question object.
@@ -134,7 +134,7 @@ The switch uses directives with the [`formControlName`](api/forms/FormControlNam
134
134
### Supply data
135
135
136
136
Another service is needed to supply a specific set of questions from which to build an individual form.
137
-
For this exercise you will create the `QuestionService` to supply this array of questions from the hard-coded sample data.
137
+
For this exercise you create the `QuestionService` to supply this array of questions from the hard-coded sample data.
138
138
In a real-world app, the service might fetch data from a backend system.
139
139
The key point, however, is that you control the hero job-application questions entirely through the objects returned from `QuestionService`.
140
140
To maintain the questionnaire as requirements change, you only need to add, update, and remove objects from the `questions` array.
@@ -177,7 +177,7 @@ To display an instance of the dynamic form, the `AppComponent` shell template pa
177
177
178
178
The example provides a model for a job application for heroes, but there are
179
179
no references to any specific hero question other than the objects returned by `QuestionService`.
180
-
This separation of model and data allows you to repurpose the components for any type of survey
180
+
This separation of model and data lets you repurpose the components for any type of survey
181
181
as long as it's compatible with the *question* object model.
182
182
183
183
### Ensuring valid data
@@ -187,7 +187,7 @@ without making any hardcoded assumptions about specific questions.
187
187
It adds both control metadata and validation criteria dynamically.
188
188
189
189
To ensure valid input, the *Save* button is disabled until the form is in a valid state.
190
-
When the form is valid, you can click *Save* and the application renders the current form values as JSON.
190
+
When the form is valid, click *Save* and the application renders the current form values as JSON.
Copy file name to clipboardExpand all lines: aio/content/guide/form-validation.md
+10-11
Original file line number
Diff line number
Diff line change
@@ -78,11 +78,10 @@ Angular then calls these functions whenever the value of the control changes.
78
78
79
79
Validator functions can be either synchronous or asynchronous.
80
80
81
-
***Sync validators**: Synchronous functions that take a control instance and immediately return either a set of validation errors or `null`. You can pass these in as the second argument when you instantiate a `FormControl`.
81
+
***Sync validators**: Synchronous functions that take a control instance and immediately return either a set of validation errors or `null`. Pass these in as the second argument when you instantiate a `FormControl`.
82
82
83
83
***Async validators**: Asynchronous functions that take a control instance and return a Promise
84
-
or Observable that later emits a set of validation errors or `null`. You can
85
-
pass these in as the third argument when you instantiate a `FormControl`.
84
+
or Observable that later emits a set of validation errors or `null`. Pass these in as the third argument when you instantiate a `FormControl`.
86
85
87
86
For performance reasons, Angular only runs async validators if all sync validators pass. Each must complete before errors are set.
88
87
@@ -93,14 +92,14 @@ You can choose to [write your own validator functions](#custom-validators), or y
93
92
The same built-in validators that are available as attributes in template-driven forms, such as `required` and `minlength`, are all available to use as functions from the `Validators` class.
94
93
For a full list of built-in validators, see the [Validators](api/forms/Validators) API reference.
95
94
96
-
To update the hero form to be a reactive form, you can use some of the same
95
+
To update the hero form to be a reactive form, use some of the same
97
96
built-in validators—this time, in function form, as in the following example.
In this example, the `name` control sets up two built-in validators—`Validators.required` and `Validators.minLength(4)`—and one custom validator, `forbiddenNameValidator`. (For more details see [custom validators](#custom-validators) below.)
102
+
In this example, the `name` control sets up two built-in validators—`Validators.required` and `Validators.minLength(4)`—and one custom validator, `forbiddenNameValidator`. (For more details see [custom validators](#custom-validators).)
104
103
105
104
All of these validators are synchronous, so they are passed as the second argument. Notice that you can support multiple validators by passing the functions in as an array.
106
105
@@ -127,7 +126,7 @@ Here's what the definition of that function looks like.
127
126
128
127
The function is a factory that takes a regular expression to detect a _specific_ forbidden name and returns a validator function.
129
128
130
-
In this sample, the forbidden name is "bob", so the validator will reject any hero name containing "bob".
129
+
In this sample, the forbidden name is "bob", so the validator rejects any hero name containing "bob".
131
130
Elsewhere it could reject "alice" or any name that the configuring regular expression matches.
132
131
133
132
The `forbiddenNameValidator` factory returns the configured validator function.
@@ -185,7 +184,7 @@ If you were to replace `useExisting` with `useClass`, then you’d be registerin
185
184
186
185
## Control status CSS classes
187
186
188
-
Angular automatically mirrors many control properties onto the form control element as CSS classes. You can use these classes to style form control elements according to the state of the form.
187
+
Angular automatically mirrors many control properties onto the form control element as CSS classes. Use these classes to style form control elements according to the state of the form.
189
188
The following classes are currently supported.
190
189
191
190
*`.ng-valid`
@@ -258,7 +257,7 @@ To provide better user experience, the template shows an appropriate error messa
This `*ngIf` displays the error if the `FormGroup` has the cross validation error returned by the `identityRevealed` validator, but only if the user has finished [interacting with the form](#dirty-or-touched).
260
+
This `*ngIf` displays the error if the `FormGroup` has the cross validation error returned by the `identityRevealed` validator, but only if the user finished [interacting with the form](#dirty-or-touched).
262
261
263
262
### Adding cross-validation to template-driven forms
264
263
@@ -272,7 +271,7 @@ Because the validator must be registered at the highest level in the form, the f
@@ -288,9 +287,9 @@ These are very similar to their synchronous counterparts, with the following dif
288
287
To convert an infinite observable into a finite one, pipe the observable through a filtering operator such as `first`, `last`, `take`, or `takeUntil`.
289
288
290
289
Asynchronous validation happens after the synchronous validation, and is performed only if the synchronous validation is successful.
291
-
This check allows forms to avoid potentially expensive async validation processes (such as an HTTP request) if the more basic validation methods have already found invalid input.
290
+
This check lets forms avoid potentially expensive async validation processes (such as an HTTP request) if the more basic validation methods have already found invalid input.
292
291
293
-
After asynchronous validation begins, the form control enters a `pending` state. You can inspect the control's `pending` property and use it to give visual feedback about the ongoing validation operation.
292
+
After asynchronous validation begins, the form control enters a `pending` state. Inspect the control's `pending` property and use it to give visual feedback about the ongoing validation operation.
294
293
295
294
A common UI pattern is to show a spinner while the async validation is being performed. The following example shows how to achieve this in a template-driven form.
Copy file name to clipboardExpand all lines: aio/content/guide/forms-overview.md
+4-4
Original file line number
Diff line number
Diff line change
@@ -22,11 +22,11 @@ Reactive forms and template-driven forms process and manage form data differentl
22
22
23
23
***Reactive forms** provide direct, explicit access to the underlying forms object model. Compared to template-driven forms, they are more robust: they're 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.
24
24
25
-
***Template-driven forms** rely on directives in the template to create and manipulate the underlying object model. They are useful for adding a simple form to an app, such as an email list signup form. They're easy to add to an app, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, template-driven forms could be a good fit.
25
+
***Template-driven forms** rely on directives in the template to create and manipulate the underlying object model. They are useful for adding a simple form to an app, such as an email list signup form. They're straightforward to add to an app, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, template-driven forms could be a good fit.
26
26
27
27
### Key differences
28
28
29
-
The table below summarizes the key differences between reactive and template-driven forms.
29
+
The following table summarizes the key differences between reactive and template-driven forms.
30
30
31
31
<style>
32
32
table {width: 100%};
@@ -69,7 +69,7 @@ Both reactive and template-driven forms are built on the following base classes.
69
69
70
70
*`FormArray` tracks the same values and status for an array of form controls.
71
71
72
-
*`ControlValueAccessor` creates a bridge between Angular `FormControl` instances and native DOM elements.
72
+
*`ControlValueAccessor` creates a bridge between Angular `FormControl` instances and built-in DOM elements.
73
73
74
74
{@a setup-the-form-model}
75
75
@@ -225,7 +225,7 @@ The following examples demonstrate the process of testing forms with reactive an
225
225
226
226
### Testing reactive forms
227
227
228
-
Reactive forms provide a relatively easy testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI.
228
+
Reactive forms provide a relatively straightforward testing strategy because they provide synchronous access to the form and data models, and they can be tested without rendering the UI.
229
229
In these tests, status and data are queried and manipulated through the control without interacting with the change detection cycle.
230
230
231
231
The following tests use the favorite-color components from previous examples to verify the view-to-model and model-to-view data flows for a reactive form.
0 commit comments