mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
docs: update signal form tutorials to use FormField
This commit is contained in:
parent
d1135f5840
commit
ddd3198dc2
22 changed files with 72 additions and 72 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
import {email, form, FormField, required, submit} from '@angular/forms/signals';
|
||||
import {bootstrapApplication} from '@angular/platform-browser';
|
||||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {form, Field, required, email, debounce, submit} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
|
|
@ -14,7 +14,7 @@ interface LoginData {
|
|||
<div>
|
||||
<label>
|
||||
Email:
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
|
||||
@if (loginForm.email().invalid()) {
|
||||
|
|
@ -29,7 +29,7 @@ interface LoginData {
|
|||
<div>
|
||||
<label>
|
||||
Password:
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
|
||||
@if (loginForm.password().invalid()) {
|
||||
|
|
@ -45,7 +45,7 @@ interface LoginData {
|
|||
</form>
|
||||
`,
|
||||
styleUrl: 'main.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class LoginApp {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
# Connect your form to the template
|
||||
|
||||
Now, you need to connect your form to the template using the `[field]` directive. This creates two-way data binding between your form model and the input elements.
|
||||
Now, you need to connect your form to the template using the `[formField]` directive. This creates two-way data binding between your form model and the input elements.
|
||||
|
||||
In this lesson, you'll learn how to:
|
||||
|
||||
- Import the `Field` directive
|
||||
- Use the `[field]` directive to bind form fields to inputs
|
||||
- Import the `FormField` directive
|
||||
- Use the `[formField]` directive to bind form fields to inputs
|
||||
- Connect text inputs and checkboxes to your form
|
||||
- Display form field values in the template
|
||||
|
||||
|
|
@ -15,17 +15,17 @@ Let's wire up the template!
|
|||
|
||||
<docs-workflow>
|
||||
|
||||
<docs-step title="Import the Field directive">
|
||||
Import the `Field` directive from `@angular/forms/signals` and add it to your component's imports array:
|
||||
<docs-step title="Import the FormField directive">
|
||||
Import the `FormField` directive from `@angular/forms/signals` and add it to your component's imports array:
|
||||
|
||||
```ts
|
||||
import { form, Field } from '@angular/forms/signals';
|
||||
import { form, FormField } from '@angular/forms/signals';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
```
|
||||
|
|
@ -33,29 +33,29 @@ import { form, Field } from '@angular/forms/signals';
|
|||
</docs-step>
|
||||
|
||||
<docs-step title="Bind the email field">
|
||||
In your template, add the `[field]` directive to the email input:
|
||||
In your template, add the `[formField]` directive to the email input:
|
||||
|
||||
```html
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
```
|
||||
|
||||
The `loginForm.email` expression accesses the email field from your form.
|
||||
</docs-step>
|
||||
|
||||
<docs-step title="Bind the password field">
|
||||
Add the `[field]` directive to the password input:
|
||||
Add the `[formField]` directive to the password input:
|
||||
|
||||
```html
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
```
|
||||
|
||||
</docs-step>
|
||||
|
||||
<docs-step title="Bind the checkbox field">
|
||||
Add the `[field]` directive to the checkbox input:
|
||||
Add the `[formField]` directive to the checkbox input:
|
||||
|
||||
```html
|
||||
<input type="checkbox" [field]="loginForm.rememberMe" />
|
||||
<input type="checkbox" [formField]="loginForm.rememberMe" />
|
||||
```
|
||||
|
||||
</docs-step>
|
||||
|
|
@ -74,6 +74,6 @@ Form field values are signals, so the displayed values update automatically as y
|
|||
|
||||
</docs-workflow>
|
||||
|
||||
Great work! You've connected your form to the template and displayed the form values. The `[field]` directive handles two-way data binding automatically - as you type, the `loginModel` signal updates, and the displayed values update immediately.
|
||||
Great work! You've connected your form to the template and displayed the form values. The `[formField]` directive handles two-way data binding automatically - as you type, the `loginModel` signal updates, and the displayed values update immediately.
|
||||
|
||||
Next, you'll learn [how to add validation to your form](/tutorials/signal-forms/3-add-validation)!
|
||||
|
|
|
|||
|
|
@ -2,20 +2,20 @@
|
|||
<div>
|
||||
<label>
|
||||
Email
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
Password
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" [field]="loginForm.rememberMe" />
|
||||
<input type="checkbox" [formField]="loginForm.rememberMe" />
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {form, Field} from '@angular/forms/signals';
|
||||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
import {form, FormField} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
|
|
@ -11,7 +11,7 @@ interface LoginData {
|
|||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class App {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Email
|
||||
<!-- TODO: Add [field]="loginForm.email" directive -->
|
||||
<!-- TODO: Add [formField]="loginForm.email" directive -->
|
||||
<input type="email" />
|
||||
</label>
|
||||
</div>
|
||||
|
|
@ -10,14 +10,14 @@
|
|||
<div>
|
||||
<label>
|
||||
Password
|
||||
<!-- TODO: Add [field]="loginForm.password" directive -->
|
||||
<!-- TODO: Add [formField]="loginForm.password" directive -->
|
||||
<input type="password" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
<!-- TODO: Add [field]="loginForm.rememberMe" directive -->
|
||||
<!-- TODO: Add [formField]="loginForm.rememberMe" directive -->
|
||||
<input type="checkbox" />
|
||||
Remember me
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
// TODO: Import Field directive from @angular/forms/signals
|
||||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
// TODO: Import FormField directive from @angular/forms/signals
|
||||
import {form} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
|
|
@ -12,7 +12,7 @@ interface LoginData {
|
|||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
// TODO: Add Field to imports array
|
||||
// TODO: Add FormField to imports array
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class App {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ Let's add validation!
|
|||
Import the `required` and `email` validators from `@angular/forms/signals`:
|
||||
|
||||
```ts
|
||||
import {form, Field, required, email} from '@angular/forms/signals';
|
||||
import {form, FormField, required, email} from '@angular/forms/signals';
|
||||
```
|
||||
|
||||
</docs-step>
|
||||
|
|
|
|||
|
|
@ -2,20 +2,20 @@
|
|||
<div>
|
||||
<label>
|
||||
Email
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
Password
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" [field]="loginForm.rememberMe" />
|
||||
<input type="checkbox" [formField]="loginForm.rememberMe" />
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {form, Field, required, email} from '@angular/forms/signals';
|
||||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
import {email, form, FormField, required} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
|
|
@ -11,7 +11,7 @@ interface LoginData {
|
|||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class App {
|
||||
|
|
|
|||
|
|
@ -2,20 +2,20 @@
|
|||
<div>
|
||||
<label>
|
||||
Email
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
Password
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" [field]="loginForm.rememberMe" />
|
||||
<input type="checkbox" [formField]="loginForm.rememberMe" />
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
// TODO: Import required and email validators
|
||||
import {form, Field} from '@angular/forms/signals';
|
||||
import {form, FormField} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
|
|
@ -12,7 +12,7 @@ interface LoginData {
|
|||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class App {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Below the email input, add conditional error display. This will only show errors
|
|||
```angular-html
|
||||
<label>
|
||||
Email
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
@if (loginForm.email().invalid() && loginForm.email().touched()) {
|
||||
<div class="error">
|
||||
|
|
@ -41,7 +41,7 @@ Below the password input, add the same pattern for password errors:
|
|||
```angular-html
|
||||
<label>
|
||||
Password
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
@if (loginForm.password().invalid() && loginForm.password().touched()) {
|
||||
<div class="error">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Email
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
@if (loginForm.email().invalid() && loginForm.email().touched()) {
|
||||
<div class="error">
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Password
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
@if (loginForm.password().invalid() && loginForm.password().touched()) {
|
||||
<div class="error">
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" [field]="loginForm.rememberMe" />
|
||||
<input type="checkbox" [formField]="loginForm.rememberMe" />
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {form, Field, required, email} from '@angular/forms/signals';
|
||||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
import {email, form, FormField, required} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
|
|
@ -11,7 +11,7 @@ interface LoginData {
|
|||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class App {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Email
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
<!-- TODO: Add @if to show errors when invalid and touched -->
|
||||
<!-- TODO: Use @for to loop through loginForm.email().errors() -->
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Password
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
<!-- TODO: Add @if to show errors when invalid and touched -->
|
||||
<!-- TODO: Use @for to loop through loginForm.password().errors() -->
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" [field]="loginForm.rememberMe" />
|
||||
<input type="checkbox" [formField]="loginForm.rememberMe" />
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {form, Field, required, email} from '@angular/forms/signals';
|
||||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
import {email, form, FormField, required} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
|
|
@ -11,7 +11,7 @@ interface LoginData {
|
|||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class App {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Let's complete the form!
|
|||
Import the `submit` function from `@angular/forms/signals`:
|
||||
|
||||
```ts
|
||||
import {form, Field, required, email, submit} from '@angular/forms/signals';
|
||||
import {form, FormField, required, email, submit} from '@angular/forms/signals';
|
||||
```
|
||||
|
||||
</docs-step>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Email
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
@if (loginForm.email().invalid() && loginForm.email().touched()) {
|
||||
<div class="error">
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Password
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
@if (loginForm.password().invalid() && loginForm.password().touched()) {
|
||||
<div class="error">
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" [field]="loginForm.rememberMe" />
|
||||
<input type="checkbox" [formField]="loginForm.rememberMe" />
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {form, Field, required, email, submit} from '@angular/forms/signals';
|
||||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
import {email, form, FormField, required, submit} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
|
|
@ -11,7 +11,7 @@ interface LoginData {
|
|||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class App {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Email
|
||||
<input type="email" [field]="loginForm.email" />
|
||||
<input type="email" [formField]="loginForm.email" />
|
||||
</label>
|
||||
@if (loginForm.email().invalid() && loginForm.email().touched()) {
|
||||
<div class="error">
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<div>
|
||||
<label>
|
||||
Password
|
||||
<input type="password" [field]="loginForm.password" />
|
||||
<input type="password" [formField]="loginForm.password" />
|
||||
</label>
|
||||
@if (loginForm.password().invalid() && loginForm.password().touched()) {
|
||||
<div class="error">
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" [field]="loginForm.rememberMe" />
|
||||
<input type="checkbox" [formField]="loginForm.rememberMe" />
|
||||
Remember me
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import {Component, signal, ChangeDetectionStrategy} from '@angular/core';
|
||||
import {ChangeDetectionStrategy, Component, signal} from '@angular/core';
|
||||
// TODO: Import submit function
|
||||
import {form, Field, required, email} from '@angular/forms/signals';
|
||||
import {email, form, FormField, required} from '@angular/forms/signals';
|
||||
|
||||
interface LoginData {
|
||||
email: string;
|
||||
|
|
@ -12,7 +12,7 @@ interface LoginData {
|
|||
selector: 'app-root',
|
||||
templateUrl: './app.html',
|
||||
styleUrl: './app.css',
|
||||
imports: [Field],
|
||||
imports: [FormField],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class App {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ You've completed the Signal Forms tutorial and built a complete login form from
|
|||
Throughout this tutorial, you learned the fundamentals of Angular Signal Forms:
|
||||
|
||||
1. **Form Models** - Creating type-safe form data with signals and the `form()` function
|
||||
2. **Field Binding** - Using the `[field]` directive for two-way data binding and displaying the field with `value()`
|
||||
2. **Field Binding** - Using the `[formField]` directive for two-way data binding and displaying the field with `value()`
|
||||
3. **Validation** - Applying built-in validators (such as `required()`, `email()`) with custom messages
|
||||
4. **Error Display** - Showing validation errors conditionally based on field state
|
||||
5. **Form Submission** - Handling form submission with the `submit()` function
|
||||
|
|
|
|||
Loading…
Reference in a new issue