![写真[1]-角度信号フォームのチュートリアル (v22) Windows 7、8、10、11 の場合 - Winpcsoft.com](https://winpcsoft.com/wp-content/plugins/wp-fastest-cache-premium/pro/images/blank.gif)
Angular でフォームを作成した場合, 二つの古い道を知っている. テンプレート駆動型のフォームは高速です, ただし搭載されている種類は少ない. リアクティブフォームは強力です, しかし、多くの儀式を持ち込んでください: フォームコントロール-, フォームグループ- および valueChanges サブスクリプション, どこで考えなければいけないのか, ログアウトする, そして毎回 ControlValueAccessor, あなたが望むなら, カスタム入力がうまく機能すること.
信号形式, Angular v22 での安定化, 別のルートを取る. フォームのステータスを単純なシグナルとして定義します, それを形で囲む() テンプレートにフィールドを含めます [フォームフィールド]. 有効, 間違い, タッチされたステータスと値はすべてシグナルとして返されます, あなたと一緒に () 読む. 購読なし, ControlValueAccess がありません, モデルからの完全な型推論.
このチュートリアルでは、全体を端から端まで説明します。. 実際のチェックアウトフォームを作成します, 組み込みバリデーターとカスタムバリデーターを追加する, 無効の場合は無効にするボタンを使用して送信をリンクし、ネストされたグループと配列フィールドをカバーします. ここのすべてのスニペットは @angular/core に基づいています 22.0.0 およびこの本の付属のコード リポジトリ. 見せてあげるよ, どのように調和するか.
より包括的な v22 イメージが最初に必要な場合, 読む Angular v22 の新機能?. この記事はフォームについてです.
ライブデモ: この投稿のすべての抜粋は、 インタラクティブな Signalformen デモセットアップは必要ありません.
Angular v22 の Signal Forms API とは何ですか?
シグナルフォームは @angular/forms/signals にあります (古典的な @angular/forms とは別のエントリ ポイント). コアピース, 最も頻繁に使用するもの:
メンタルモデル: 信号にはデータが含まれています, 形状() それらをリアクティブフィールドツリーにパッケージ化し、各フィールドが独自の信号を提供します。. モデルは唯一の真実の情報源であり、フォームは双方向でモデルと同期したままになります。.
ステップ 1: 形状ステータスを信号として定義
単純な書き込み可能な信号から始める, フォームの形状を表すもの. ここに入力したタイプはフォーム全体に流れます, そのため、オートコンプリートとコンパイルエラーが無料で発生します.
輸入 { 信号 } from '@angular/core'; フォームモデル = 信号({
方法: '',
額: 100,
}); これは「モデル」レベル全体です. フォームグループがありません, ネストされたビルダー呼び出しはまだありません, 信号内の単なるオブジェクトリテラル.
ステップ 2: フォームでフォームを作成する()
モデルをフォームで包みます() ある. 2 番目の引数はスキーマ コールバックです。, モデル内の型指定されたパスに基づいて検証を宣言する場所.
輸入 { 成分, 信号, 注入する } from '@angular/core';
輸入 { 形状, フォームフィールド, 必須 } from '@angular/forms/signals'; @成分({
セレクタ: 'app-checkout-form',
輸入品: [フォームフィールド],
テンプレート: 「...」,
})
エクスポートクラス CheckoutFormComponent {
フォームモデル = 信号({ 方法: '', 額: 100 }); checkoutForm = フォーム(this.formModel, (スキーマ) => {
必須(スキーマ.メソッド, { メッセージ: 'Please select a payment method.' });
必須(スキーマ.量, { メッセージ: 'Amount is required.' });
});
} schema.method と schema.amount は型指定されたパスです, 文字列なし. フィールド名を入力すると, ビルドが失敗する. required は、メッセージを含むオプションの構成オブジェクトを受け取ります, それはまさにそれです, 後でユーザーに表示するもの.
checkoutForm がフィールド ツリーになりました. checkoutFormを使用してフォーム全体のステータスを確認できます() checkoutForm.method を使用した個々のフィールド.
ステップ 3: フィールドのリンク先 [フォームフィールド]
テンプレートで、各コントロールを [フォームフィールド] 指令, 対応するフィールドを指します. これにより、値のバインディングとステータスの更新が両方向で行われるようになります。, 基礎となる信号が最新の状態に保たれるようにする, ユーザーが何かを入力または選択している間.
<形状 (提出する)="onSubmit(); $イベント.preventDefault()">
<label for="payment-method">支払い方法を選択してください</ラベル>
<select id="payment-method" [フォームフィールド]="checkoutForm.method">
<option value="">方法を選択してください...</オプション>
<option value="credit">クレジットカード</オプション>
<option value="paypal">ペイパル</オプション>
</選択する>
<label for="amount">額 ($)</ラベル>
<input id="amount" type="number" [フォームフィールド]="checkoutForm.amount" />
<button type="submit" [無効]="checkoutForm().無効()">
支払う {{ checkoutForm.amount().価値() | 通貨 }}
</ボタン>
</形状>
いくつかのこと, 考慮する必要があること:
- [フォームフィールド]="checkoutForm.method" ネイティブを結びつける
- checkoutForm.amount().価値() 現在のフィールド値を信号として読み取ります, ボタンのラベルがライブで更新されるようにする.
- チェックアウトフォーム().無効() フォーム全体の有効性を読み取ります. 私たちはそれを使います, 送信を無効にするには.
覚えておいてください, FormField をコンポーネントのインポート配列に追加します, スタンドアロンコンポーネントは指示のみを参照するため, 彼らが輸入していること.
ステップ 4: @if を使用して検証エラーを表示する
各フィールドは .invalid を表します(), .触れた() および .errors() 信号として準備完了. いつものパターンはこれ, エラーを最初に表示する, ユーザーがフィールドに触れた後, そしてエラーリストを調べます. エラーにはタイプとオプションのメッセージが含まれます.
<select id="payment-method" [フォームフィールド]="checkoutForm.method">
<option value="">方法を選択してください...</オプション>
<option value="credit">クレジットカード</オプション>
<option value="paypal">ペイパル</オプション>
</選択する>
@もし (checkoutForm.メソッド().無効() && checkoutForm.メソッド().触れた()) {
<div class="error-msg">
@のために (checkoutForm.methodのエラー().エラー(); トラックエラーの種類) {
<スパン>{{ エラーメッセージ }}</スパン>
}
</ディビジョン>
} track error.kind はここでの正しいキーです, 各バリデーターが一種のエラーに寄与するため、 (必要, 電子メール, あなたのカスタムスタイルなど). 購読なし, コンポーネント全体に散在する no markAsTouched 呼び出し. タッチされた状態が追跡され、信号として出力されます。.
ステップ 5: カスタムバリデーターを追加する
組み込みのバリデーターは最も一般的なケースをカバーします, ただし、実際のフォームには常にカスタム ルールが必要です. 「検証」を使用します。(パス, ふん)「. この関数は、フィールドの値信号を含むコンテキストと、他のフィールドを読み取るための valueOf ヘルパーを受け取ります。. タイプとメッセージを含むエラー オブジェクトを返すか、null を返します。, フィールドが有効な場合.
輸入 { 形状, 必須, 検証する } from '@angular/forms/signals'; checkoutForm = フォーム(this.formModel, (スキーマ) => {
必須(スキーマ.メソッド, { メッセージ: 'Please select a payment method.' }); // カスタムルール: 金額は制限を下回る正の数である必要があります.
検証する(スキーマ.量, ({ 価値 }) => {
定数 = 値();
もし (額 <= 0) {
戻る { 親切: 'minAmount', メッセージ: 'Amount must be greater than zero.' };
}
もし (額 > 10000) {
戻る { 親切: 'maxAmount', メッセージ: 'Amount cannot exceed $10,000.' };
}
nullを返す;
});
});
カスタムエラーはありません()-ヘルパー. カスタム エラーは、タイプとオプションのメッセージを持つ単純なオブジェクトです。. このオブジェクトは .errors に流れ込みます。()-フィールドの配列, したがって、同じ @for テンプレートが付属しています (のエラー …; トラックエラーの種類) 追加の労力を必要とせずにレンダリングされます.
クロスフィールド検証
バリデーターコンテキストが値「valueOf」を返すためです。, クロスフィールドのルールは簡単です. valueOf を使用した別のフィールドの読み取りはリアクティブです, ルールが再度実行されるようにする, このフィールドが変更されると. Ein Klassiker "Passwörter müssen übereinstimmen" チェック:
輸入 { 形状, 必須, 検証する } from '@angular/forms/signals'; サインアップフォーム = フォーム(this.signupModel, (スキーマ) => {
必須(スキーマ.パスワード);
必須(スキーマ.confirmPassword); 検証する(スキーマ.confirmPassword, ({ 価値, の値 }) => {
もし (価値() !== の値(スキーマ.パスワード)) {
戻る { 親切: 'passwordMismatch', メッセージ: 'Passwords do not match.' };
}
nullを返す;
});
}); ステップ 6: 送信と無効化の処理, 無効である限り
すでに「送信」ボタンが無効になっています [無効]="checkoutForm().無効()". 送信ハンドラー自体の有効性に注意し、フォームから入力された値を読み取ります。. 値は元のモデルから完全に入力されます.
輸入 { 成分, 信号, 注入する } from '@angular/core';
輸入 { 形状, フォームフィールド, 必須 } from '@angular/forms/signals';
輸入 { 支払いサービス } from './payment.service'; エクスポートクラス CheckoutFormComponent {
privatepaymentService=注入(支払いサービス);
支払い結果 = シグナル<{ 成功: ブール値; トランザクションID: 弦 } | ヌル>(ヌル); フォームモデル = 信号({ 方法: '', 額: 100 });
checkoutForm = フォーム(this.formModel, (スキーマ) => {
必須(スキーマ.メソッド);
必須(スキーマ.量);
}); 送信時() {
もし (this.checkoutForm().有効()) {
定数 { 方法, 額 } = this.checkoutForm().価値();
const result = this.paymentService.processPayment(方法, 額);
this.paymentResult.set(結果);
}
}
} より高度なプロセスの場合、Signal Forms は送信も提供します。()-@angular/forms/signals の機能. 非同期アクションを実行します, タッチされたフィールドにマークを付け、実行を拒否します, solange das Formular ungültig ist oder eine Übermittlung bereits läuft. Das obige Handbuch zu onSubmit reicht für einfache Fälle aus; Greifen Sie auf „submitte()“ zu, wenn Sie die integrierte Lebenszyklusbehandlung für Serveraufrufe wünschen.
Dieses vollständige Checkout-Beispiel, einschließlich eines barrierefreien Akkordeons, das mit Angular Aria erstellt wurde, befindet sich im Code-Repository des Buchs unter apps/chapter-06/src/app/checkout-form.
Verschachtelte und gruppierte Felder
Verschachtelte Objekte benötigen keine spezielle API. Verschachteln Sie sie im Modell und der Feldbaum spiegelt die Form wider. Sie binden verschachtelte Felder mit gepunkteten Pfaden und validieren sie auf verschachtelten Schemapfaden.
フォームモデル = 信号({
customer: {
名前: '',
電子メール: '',
},
額: 100,
}); checkoutForm = フォーム(this.formModel, (スキーマ) => {
必須(schema.customer.name, { メッセージ: 'Name is required.' });
必須(schema.customer.email, { メッセージ: 'Email is required.' });
電子メール(schema.customer.email, { メッセージ: 'Enter a valid email.' });
}); <入力 [フォームフィールド]="checkoutForm.customer.name" />
<入力 [フォームフィールド]="checkoutForm.customer.email" />
@もし (checkoutForm.customer.email().無効() && checkoutForm.customer.email().触れた()) {
<div class="error-msg">
@のために (checkoutForm.customer.email のエラー().エラー(); トラックエラーの種類) {
<スパン>{{ エラーメッセージ }}</スパン>
}
</ディビジョン>
} メールアドレスは分に次ぐものです, 最大, 最小の長さ, 組み込みバリデーターの maxLength と Pattern 1, これらはすべて @angular/forms/signals からインポートされました. 誰もが同じことを受け入れます { メッセージ }-構成, コピーを制御できるようにする.
アレイフェルダー
繰り返し行の場合は、モデル内に配列を保持し、applyEach で各要素を検証します。. 配列内の各要素にスキーマを適用し、その要素スキーマ内で要素自体のパスに対してスキーマを検証します。.
輸入 { 形状, 必須, 適用するそれぞれ } from '@angular/forms/signals'; orderModel = 信号({
アイテム: [
{ 名前: '', 量: 1 },
],
}); オーダーフォーム = フォーム(this.orderModel, (スキーマ) => {
適用するそれぞれ(スキーマ.アイテム, (アイテム) => {
必須(アイテム名, { メッセージ: 'Item name is required.' });
必須(品目.数量);
});
}); テンプレートで、@for を使用してフィールド ツリーの要素を反復処理し、各行をバインドします。. 行を追加または削除するには, .update でソース信号を更新します(); フィールドツリーは自動的に反応します.
@のために (orderForm.itemsの項目; $indexを追跡する) {
<div class="row">
<入力 [フォームフィールド]="item.name" />
<input type="number" [フォームフィールド]="item.quantity" />
</ディビジョン>
} <button type="button" (クリック)="addItem()">アイテムの追加</ボタン>
addItem() {
this.orderModel.update((モデル) => ({
...モデル,
アイテム: [...モデル.アイテム, { 名前: '', 量: 1 }],
}));
} 配列は信号内の単なるデータであるため、, 不変の更新パターンで変更する, すでに信号に使用しているもの. FormArray API はありません, 個別に学習できるもの.
シグナルフォルメン vs. 反応性形態
どちらもバージョンにあります 22 ファーストクラス, したがって、これは選択であり、移行の義務ではありません. 正直な比較はこちら.
Signal Forms が削除するもの, 最も目立つのは2か所です: カスタム コントロールの ControlValueAccessor ダンスと、valueChanges に関する手動サブスクリプション管理. あなたの反応性がすでにシグナル指向である場合, 信号形式によりこれが保証されます, ずっと一つのメンタルモデルに留まっているということ.
リアクティブ フォームを引き続き使用する必要がある場合
現実的であること. リアクティブフォームを選択する, もし:
- Reactive Forms 用の大規模なコードベースがすでにあり、書き直す価値はありません.
- valueChanges ではなく RxJS 演算子に大きく依存しています。 (デバウンスされたサーバー検索, 複雑なストリーム構成). この相互運用性は、現在、クラシック API でより成熟しています。.
- サードパーティのライブラリ, あなたが依存していること, ControlValueAccessor を期待しています- または FormGroup インスタンス.
新しいコードの新しいフォームの場合、シグナルフォームはバージョンにあります 22 よりクリーンなデフォルト設定. これは他のすべてに当てはまります: 移行する, 価値が明確なとき, そしてそうではありません, APIが新しいため. あなたのより広い目標がそれであるなら、, リアクティブなコードベースをシグナルに向けて移動する, です RxJS からシグナルへの移行ガイド パターンをカバーします, そして NgRx からシグナルへのガイド 国家行政をカバーする.
よくある落とし穴
いくつかのこと, 早い段階で人々を動揺させる:
- インポートパスが正しくありません. シグナルフォームは @angular/forms/signals から取得されます。, @angular/forms からのものではありません. それらを混同することは、最も一般的な最初の間違いです.
- インポートを忘れた フォームフィールド. スタンドアロン コンポーネントはインポートにそれをリストする必要があります, または [フォームフィールド] 黙って何もしない.
- タッチする前にエラーを表示する. .touched でゲートエラー表示(), ユーザーが初めてフォームを試したときに、フォームが叫び声を上げないようにするためです。. .invalid を結合する() 触れた().
- モデルを適切に変更する. .set を使用してソース信号を不変に更新します() または .update(). インプレース突然変異は期待される反応性を引き起こさない.
- 期待してください カスタムエラー()-ヘルパー. 何もありません. カスタムバリデーターは簡単な結果を提供します { 親切, メッセージ }-オブジェクトを返すかnullを返す.
- 手を差し伸べる フォーム配列. 配列は信号内の単なる配列です; 要素ごとの検証には applyEach を使用します.
よくある質問
Angular v22 安定版の Ist シグナルフォーム?
そして. Signal Forms は Angular v22 で安定版に変換されました. それらはバージョンにありました 21 プレビューおよびバージョンとして導入 22 Angular Aria とともに安定化, 完全なドキュメントと Angular マテリアルと Angular Aria の追加サポート付き.
波形のインポートパスとは何ですか?
すべては @angular/forms/signals から来ています: 形状, フォームフィールド, 必要, 検証する, 電子メール, 分, 最大, 最小の長さ, 最大長さ, パターン, applyEach と送信. これは、古典的な @angular/forms とは別のエントリ ポイントです。.
シグナルフォームにカスタムバリデーターを追加するにはどうすればよいですか?
「検証」を使用します。(パス, ふん)” スキーマ コールバック内. この関数は、タイプとオプションのメッセージまたは null を含む単純なエラー オブジェクトを返します。, 有効な場合. 値を使用してフィールド自体の値を読み取ります()-valueOf を持つコンテキストおよびその他のフィールドの信号(…).
フォームの値と有効性を読み取るにはどうすればよいですか?
それらは信号です. myForm.fieldName を使用してフィールド値を読み取る().価値(), .valid によるフィールドの有効性() / .無効(), .touched でタッチされた状態() および .errors のエラー(). フォーム全体の有効性は myForm です().有効() / 私のフォーム().無効().
シグナルフォームをリアクティブフォームに置き換える?
いいえ. どちらも v22 でサポートされています. 波形は新しいシグナルファーストコードのよりクリーンなデフォルトです. リアクティブ フォームは、既存のコードベースや、valueChanges ワークフローよりも大規模な RxJS にとって引き続き優れた選択肢です。.
配列フィールドを扱うにはどうすればよいですか (繰り返しフィールド) 1つ?
モデル信号に配列を保持し、applyEach を使用して要素ごとにスキーマを適用します(スキーマ.アイテム, (アイテム) => { … }) の. @for を使用して行をレンダリングし、それぞれをバインドします [フォームフィールド]行を追加または削除します, ソース信号を常に更新することによって.
さらに深く進む
このチュートリアルはシグナルフォームの中核です, しかし、実稼働形式ではさらに多くのことが提供されます: Angular Aria を使用したアクセス可能な構造, リソースでサポートされる非同期検証と、フォームが完全に信号駆動型のコンポーネントにどのように適合するか. 章 6 フォン マスターアングル信号 完全なチェックアウト フォームをエンドツーエンドで作成します, Angular Aria キーボードのヘッドレス命令で Signal Forms を使用する- スクリーン リーダーのサポートと、新しい @Service によるシグナルベースのサービスとの組み合わせ()-デコレータ接続. 各例は v22 コード リポジトリに対応します.
この本は、AI と Angular の Google 開発者専門家によって書かれています。, Angular チームからの序文付き. 始めましょう リーンパブPDF と EPUB、および無料のアップデートを入手できる場所: https://leanpub.com/mastering-angular-signals. それもオンです アマゾナス州. の詳細情報 書籍のランディングページ.
![]()
角度信号フォームのチュートリアル (v22) 元々は Google Developer Experts on Medium で公開されました, 人々が会話を続ける場所, このストーリーをハイライトして返信することで.
