Angular 表单(2):验证

验证

使用表单验证的设置如下:

在app.module.ts文件中,导入FormsModule模块。
    フォームモジュールを使うには
2. 添加组件TS文件中的Validators的导入。
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
在组件的TS文件中的ngOnInit()函数中为每个表单控件设置验证规则。
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({ 省略 })
export class SampleComponent implements OnInit {

  title!:string;
  message!:string;
  sampleForm!: FormGroup;

  constructor(
    private formBuilder:FormBuilder
  ) { }

  ngOnInit(): void {
    this.title = 'Hello-app';
    this.message = 'FormControlを使う';

    this.sampleForm = this.formBuilder.group({
      name: ['', [Validators.required, Validators.minLength(1)]],
      email: ['', [Validators.required, Validators.email]],
      age: [0, [Validators.min(1), Validators.max(150)]]
    });
  }

  get name() { return this.sampleForm.get('name'); }
  get email() { return this.sampleForm.get('email'); }
  get age() { return this.sampleForm.get('age'); }
}
4. HTML组件
<div id="body">
  <h1>{{title}}</h1>
  <p>メッセージ:{{message}}</p>
  <form [formGroup]="sampleForm">
    <table>
      <tr>
        <th>名前:</th>
        <td>
          <input type="text" formControlName="name">
          <ng-container *ngIf="name?.invalid && (name?.dirty || name?.touched)">
            <div *ngIf="name?.errors?.['required'] === true" class="error">名前は必須入力です。</div>
          </ng-container>
        </td>
      </tr>
      <tr>
        <th>Eメール:</th>
        <td>
          <input type="text" formControlName="email">
          <ng-container *ngIf="email?.invalid && (email?.dirty || email?.touched)">
            <div *ngIf="email?.errors?.required" class="error">Eメールは必須入力です。</div>
            <div *ngIf="email?.errors?.email" class="error">Eメールのフォーマット不正です。</div>
          </ng-container>
        </td>
      </tr>
      <tr>
        <th>年齢:</th>
        <td>
          <input type="number" formControlName="age">
          <ng-container *ngIf="age?.invalid && (age?.dirty || age?.touched)">
            <div *ngIf="age?.errors?.min" class="error">年齢は1才以上でなければなりません。</div>
            <div *ngIf="age?.errors?.max" class="error">年齢は150才以下でなければなりません。</div>
          </ng-container>
        </td>
      </tr>
    </table>
    <input type="button" value="クリック" [disabled]="sampleForm.invalid">
  </form>
</div>
    クリックボタンの [disabled]=”sampleForm.invalid” は、エラーがなければ、使用できるようにするための設定です。
小心要点

尽管按照示例进行了描述,但在确认检查结果时,使用ngIf进行编译时出现了错误。由于解决这个问题花费了一些时间,所以我留下了备忘录。

Error: src/app/sample/sample.component.html:10:59 - error TS2531: Object is possibly 'null'.

10           <div *ngIf="name.invalid && (name.dirty || name.touched)">
                                                             ~~~~~~~

将「name.touch」修改为「name?.touch」后,错误得到解决。这个描述似乎可以避免在出现空值时出现错误。

在属性声明中,如果不进行初始化,编辑器会出现错误。使用VS Code中的快速修复功能,错误就消失了。

    「Add ‘undefined’ type to property ‘sampleForm’」を選択した場合

样本表单: FormGroup | undefined;

属性声明不会引发错误,但由于参考位置可能为undefined,因此发生了错误。

    「Add definite assignment assertion to property ‘sampleForm:FormGroup’」を選択した場合

样本表单!:FormGroup

由于错误被修复,因此这个定义似乎是最佳选择。

可能的翻译:
与示例和书籍不同,实际上出现错误的现象可能是因为使用的Angular或Node.js版本更新,导致了TypeScript的检查更加严格。

$ ng version
Your global Angular CLI version (13.1.0) is greater than your local version (12.1.4). The local Angular CLI version is used.

To disable this warning use "ng config -g cli.warnings.versionMismatch false".

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 12.1.4
Node: 16.13.1 (Unsupported)
Package Manager: npm 8.1.2
OS: win32 x64

Angular: 12.1.5
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1201.4
@angular-devkit/build-angular   12.1.4
@angular-devkit/core            12.1.4
@angular-devkit/schematics      12.1.4
@angular/cli                    12.1.4
@schematics/angular             12.1.4
rxjs                            6.6.7
typescript                      4.3.5

Warning: The current version of Node (16.13.1) is not supported by Angular.

单独验证

メソッド名 (c: FormControl) {

  //問題がない場合
  return null;

  // 問題がある場合
  //return { 名前: { valid: boolean値, ... } };
  return { 名前: boolean値 };
}

作为示例,我已经添加了一个验证日语的名字。以下是摘录。

组件TS文件。
export class SampleComponent implements OnInit {

  ngOnInit(): void {

    this.sampleForm = this.formBuilder.group({
      name: ['', [Validators.required, this.isJapanese]],
      email: ['', [Validators.required, Validators.email]],
      age: [0, [Validators.min(1), Validators.max(150)]]
    });
  }

  isJapanese(c: FormControl) {
    console.log(JSON.stringify(c.value));
    if (c.value == null || c.value == "") {
      return null;
    }
    if (c.value.match(/^[\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf]+$/)) {
      return null;
    }
    return { isJapanese: false };
  }

}

组件HTML文件

      <tr>
        <th>名前:</th>
        <td>
          <input type="text" formControlName="name">
          <ng-container *ngIf="name?.invalid && (name?.dirty || name?.touched)">
            <div *ngIf="name?.errors?.['required'] === true" class="error">名前は必須入力です。</div>
            <div *ngIf="name?.errors?.isJapanese === false" class="error">日本語で入力して下さい。</div>
          </ng-container>
        </td>
      </tr>

相关文章

    • Angular はじめに覚えること

 

    • Angular フォーム (1):基礎

 

    Angular 次に覚えること

请查阅参考资料。

    • 『Angular超入門』 著者:掌田 津邪乃

 

    • https://angular.jp/start

 

    • https://angular.jp/guide/form-validation

 

    • https://hepokon365.hatenablog.com/entry/2020/08/23/220835

 

    • https://itblog.verdy-it.xyz/ypescript型宣言字のクエスチョンマークとビックリマ/

 

    • Angularの便利タグng-container, ng-content, ng-template

 

    • javascript 日本語チェックです

 

    JavaScriptでひらがな・カタカタ・漢字をチェックする方法まとめ
广告
将在 10 秒后关闭
bannerAds