mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
docs: iterate on signal forms essential guide
This commit is contained in:
parent
a55a96a5fb
commit
d02374a45c
7 changed files with 36 additions and 26 deletions
|
|
@ -6,8 +6,8 @@ import {form, Field} from '@angular/forms/signals';
|
|||
*/
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrl: 'app.component.css',
|
||||
templateUrl: 'app.html',
|
||||
styleUrl: 'app.css',
|
||||
imports: [Field],
|
||||
})
|
||||
export class App {
|
||||
|
|
@ -6,8 +6,8 @@ import {form, Field, required, email, submit} from '@angular/forms/signals';
|
|||
*/
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrl: 'app.component.css',
|
||||
templateUrl: 'app.html',
|
||||
styleUrl: 'app.css',
|
||||
imports: [Field],
|
||||
})
|
||||
export class App {
|
||||
|
|
@ -2,11 +2,15 @@
|
|||
Signal Forms is built on Angular signals to provide a reactive, type-safe way to manage form state.
|
||||
</docs-decorative-header>
|
||||
|
||||
## How it works
|
||||
Signal Forms manage form state using Angular signals to provide automatic synchronization between your data model and the UI.
|
||||
|
||||
### 1. Create a signal model
|
||||
This guide walks you through the core concepts to create forms with Signal Forms. Here's how it works:
|
||||
|
||||
When you create a form, you start by creating a signal that holds the state of your form:
|
||||
## Creating your first form
|
||||
|
||||
### 1. Create a form model
|
||||
|
||||
When you create a form, you start by creating a signal that holds your form's data:
|
||||
|
||||
```ts
|
||||
const loginModel = signal({
|
||||
|
|
@ -15,9 +19,9 @@ const loginModel = signal({
|
|||
});
|
||||
```
|
||||
|
||||
### 2. Pass the data model to `form()`
|
||||
### 2. Pass the form model to `form()`
|
||||
|
||||
Then, you pass your form model into the `form()` function to create a form tree that mirrors and enhances your model's structure:
|
||||
Then, you pass your form model into the `form()` function to create a **field tree** - an object structure that mirrors your model's shape, allowing you to access fields with dot notation:
|
||||
|
||||
```ts
|
||||
form(loginModel);
|
||||
|
|
@ -46,11 +50,17 @@ loginForm.email().value.set('alice@wonderland.com');
|
|||
console.log(loginModel().email); // 'alice@wonderland.com'
|
||||
```
|
||||
|
||||
NOTE: The `[field]` directive also syncs field state for attributes like `required`, `disabled`, and `readonly` when appropriate. You can read more in the upcoming in-depth guide.
|
||||
NOTE: The `[field]` directive also syncs field state for attributes like `required`, `disabled`, and `readonly` when appropriate.
|
||||
|
||||
### 4. Read form field values with `value()`
|
||||
|
||||
Finally, you can access field values as reactive signals by calling the field as a function and accessing its `value()`:
|
||||
You can access field state by calling the field as a function. This returns a `FieldState` object containing reactive signals for the field's value, validation status, and interaction state:
|
||||
|
||||
```ts
|
||||
loginForm.email() // Returns FieldState with value(), valid(), touched(), etc.
|
||||
```
|
||||
|
||||
To read the field's current value, access the `value()` signal:
|
||||
|
||||
```html
|
||||
<!-- Render form value that updates automatically as user types -->
|
||||
|
|
@ -64,10 +74,10 @@ const currentEmail = loginForm.email().value();
|
|||
|
||||
Here's a complete example:
|
||||
|
||||
<docs-code-multifile preview path="adev/src/content/examples/signal-forms/src/login-simple/app/app.component.ts">
|
||||
<docs-code header="app/app.component.ts" path="adev/src/content/examples/signal-forms/src/login-simple/app/app.component.ts"/>
|
||||
<docs-code header="app/app.component.html" path="adev/src/content/examples/signal-forms/src/login-simple/app/app.component.html"/>
|
||||
<docs-code header="app/app.component.css" path="adev/src/content/examples/signal-forms/src/login-simple/app/app.component.css"/>
|
||||
<docs-code-multifile preview path="adev/src/content/examples/signal-forms/src/login-simple/app/app.ts">
|
||||
<docs-code header="app.ts" path="adev/src/content/examples/signal-forms/src/login-simple/app/app.ts"/>
|
||||
<docs-code header="app.html" path="adev/src/content/examples/signal-forms/src/login-simple/app/app.html"/>
|
||||
<docs-code header="app.css" path="adev/src/content/examples/signal-forms/src/login-simple/app/app.css"/>
|
||||
</docs-code-multifile>
|
||||
|
||||
## Basic usage
|
||||
|
|
@ -187,12 +197,12 @@ NOTE: Multiple select (`<select multiple>`) is not supported by the `[field]` di
|
|||
|
||||
## Validation and state
|
||||
|
||||
Signal Forms provides built-in validators that you can apply to your form fields. To add validation, pass a schema function as the second argument to `form()`. This function receives a field **path** (sometimes abbreviated as `p`) that allows you to reference the model and its subsequent fields:
|
||||
Signal Forms provides built-in validators that you can apply to your form fields. To add validation, pass a schema function as the second argument to `form()`. This function receives a **field path** parameter that allows you to reference the fields in your form model:
|
||||
|
||||
```ts
|
||||
const loginForm = form(loginModel, (p) => {
|
||||
required(p.email);
|
||||
email(p.email);
|
||||
const loginForm = form(loginModel, (fieldPath) => {
|
||||
required(fieldPath.email);
|
||||
email(fieldPath.email);
|
||||
});
|
||||
```
|
||||
|
||||
|
|
@ -211,19 +221,19 @@ required(p.email, { message: 'Email is required' });
|
|||
email(p.email, { message: 'Please enter a valid email address' });
|
||||
```
|
||||
|
||||
Each form field exposes its validation state through signals. For example, you can check `field.valid()` to see if validation passes, `field.touched()` to see if the user has interacted with it, and `field.errors()` to get the list of validation errors.
|
||||
Each form field exposes its validation state through signals. For example, you can check `field().valid()` to see if validation passes, `field().touched()` to see if the user has interacted with it, and `field().errors()` to get the list of validation errors.
|
||||
|
||||
Here's a complete example:
|
||||
|
||||
<docs-code-multifile preview path="adev/src/content/examples/signal-forms/src/login-validation/app/app.component.ts">
|
||||
<docs-code header="app/app.component.ts" path="adev/src/content/examples/signal-forms/src/login-validation/app/app.component.ts"/>
|
||||
<docs-code header="app/app.component.html" path="adev/src/content/examples/signal-forms/src/login-validation/app/app.component.html"/>
|
||||
<docs-code header="app/app.component.css" path="adev/src/content/examples/signal-forms/src/login-validation/app/app.component.css"/>
|
||||
<docs-code-multifile preview path="adev/src/content/examples/signal-forms/src/login-validation/app/app.ts">
|
||||
<docs-code header="app.ts" path="adev/src/content/examples/signal-forms/src/login-validation/app/app.ts"/>
|
||||
<docs-code header="app.html" path="adev/src/content/examples/signal-forms/src/login-validation/app/app.html"/>
|
||||
<docs-code header="app.css" path="adev/src/content/examples/signal-forms/src/login-validation/app/app.css"/>
|
||||
</docs-code-multifile>
|
||||
|
||||
### Field State Signals
|
||||
|
||||
Each field provides these state signals:
|
||||
Every `field()` provides these state signals:
|
||||
|
||||
| State | Description |
|
||||
| ------------ | -------------------------------------------------------------------------- |
|
||||
|
|
@ -234,4 +244,4 @@ Each field provides these state signals:
|
|||
| `pending()` | Returns `true` if async validation is in progress |
|
||||
| `errors()` | Returns an array of validation errors with `kind` and `message` properties |
|
||||
|
||||
TIP: Show errors only after `touched()` is true to avoid displaying validation messages before the user has interacted with a field.
|
||||
TIP: Show errors only after `field().touched()` is true to avoid displaying validation messages before the user has interacted with a field.
|
||||
|
|
|
|||
Loading…
Reference in a new issue