首頁  >  文章  >  web前端  >  一文聊聊angular中的響應式表單

一文聊聊angular中的響應式表單

青灯夜游
青灯夜游轉載
2022-01-12 18:58:211814瀏覽

這篇文章帶大家聊聊angular中的響應式表單,介紹一下全域註冊響應式表單模組、新增基礎表單控制項、把表單控制項分組的方法,希望對大家有幫助!

一文聊聊angular中的響應式表單

響應式表單

Angular 提供了兩種不同的方法來透過表單處理使用者輸入:回應式表單範本驅動表單。 【相關教學推薦:《angular教學》】

  • 響應式表單:提供對底層表單物件模型直接、明確的存取。它們與範本驅動表單相比,更加健壯。如果表單是你的應用程式的關鍵部分,或者你已經在使用響應式表單來建立應用,那就使用響應式表單。
  • 範本驅動表單:依賴範本中的指令來建立和操作底層的物件模型。它們對於為應用程式添加一個簡單的表單非常有用,例如電子郵件清單註冊表單。

這裡只介紹響應式表單,範本驅動表單請參考官網—https://angular.cn/guide/forms-overview#setup-in-template-driven-forms

全域註冊響應式表單模組ReactiveFormsModule

要使用響應式表單控件,就要從@angular/forms 套件中匯入ReactiveFormsModule,並把它加到你的NgModuleimports陣列中。如下:app.module.ts

/***** app.module.ts *****/
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [
    // other imports ...
    ReactiveFormsModule
  ],
})
export class AppModule { }

新增基礎表單控制項 FormControl

使用表單控制項有三個步驟。

  • 在你的應用程式中註冊響應式表單模組。這個模組聲明了一些你要用在響應式表單中的指令。

  • 產生一個新的 FormControl 實例,並把它保存在元件中。

  • 在範本中註冊這個 FormControl

要註冊表單控制項,就要匯入FormControl類別並建立一個FormControl的新實例,將其儲存為類別的屬性。如下:test.component.ts

/***** test.component.ts *****/
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

@Component({
  selector: 'app-name-editor',
  templateUrl: './name-editor.component.html',
  styleUrls: ['./name-editor.component.css']
})
export class TestComponent {
	// 可以在 FormControl 的构造函数设置初始值,这个例子中它是空字符串
  name = new FormControl('');
}

然後在模板中註冊該控件,如下:test.component.html

<!-- test.component.html -->
<label>
  Name: <input type="text" [formControl]="name">
</label>
<!-- input 中输入的值变化的话,这里显示的值也会跟着变化 -->
<p>name: {{ name.value }}</p>

#FormControl 的其它屬性和方法,請參閱API 參考手冊:

https://angular.cn/api/forms/FormControl#formcontrol

把表單控制項分組FormGroup

就像FormControl 的實例能讓你控制單一輸入框所對應的控制項一樣,FormGroup 的實例也能追蹤一組FormControl 實例(例如表單)的表單狀態。當建立 FormGroup 時,其中的每個控制項都會根據其名字進行追蹤。

看下例示範:test.component.tstest.component.html

import { Component } from &#39;@angular/core&#39;;
import { FormControl, FormGroup, Validators } from &#39;@angular/forms&#39;

@Component({
  selector: &#39;app-test&#39;,
  templateUrl: &#39;./test.component.html&#39;,
  styleUrls: [&#39;./test.component.css&#39;]
})
export class TestComponent implements OnInit {
    constructor() {}

    profileForm = new FormGroup({
      firstName: new FormControl(&#39;&#39;, [Validators.required,Validators.pattern(&#39;[a-zA-Z0-9]*&#39;)]),
      lastName: new FormControl(&#39;&#39;, Validators.required),
    });
	
	onSubmit() {
		// 查看控件组各字段的值
      console.log(this.profileForm.value)
    }
}
<!-- profileForm 这个 FormGroup 通过 FormGroup 指令绑定到了 form 元素,在该模型和表单中的输入框之间创建了一个通讯层 -->
<!-- FormGroup 指令还会监听 form 元素发出的 submit 事件,并发出一个 ngSubmit 事件,让你可以绑定一个回调函数。 -->
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
    <label>
<!-- 由 FormControlName 指令把每个输入框和 FormGroup 中定义的表单控件 FormControl 绑定起来。这些表单控件会和相应的元素通讯 -->
      First Name: <input type="text" formControlName="firstName">
    </label>
    <label>
      Last Name: <input type="text" formControlName="lastName">
    </label>
    <button type="submit" [disabled]="!profileForm.valid">Submit</button>
  </form>

  <p>{{ profileForm.value }}</p>
  <!-- 控件组的状态: INVALID 或 VALID -->
  <p>{{ profileForm.status }}</p>	
  <!-- 控件组输入的值是否为有效值: true 或 false-->
  <p>{{ profileForm.valid }}</p>
  <!-- 是否禁用: true 或 false-->
  <p>{{ profileForm.disabled }}</p>

##FormGroup 的其它屬性和方法,請參閱API 參考手冊:

https://angular.cn/api/forms/FormGroup#formgroup

##使用更簡單的FormBuilder服務產生控制項實例

在響應式表單中,當需要與多個表單處理時,手動建立多個表單控制項實例會非常繁瑣。

FormBuilder

服務提供了一些便利方法來產生表單控制項。 FormBuilder在幕後也使用同樣的方式來建立和傳回這些實例,只是用起來更簡單。

FormBuilder

是一個可注入的服務提供者,它是由 ReactiveFormModule 提供的。只要把它加到元件的建構函式中就可以注入這個依賴。

FormBuilder

服務有三個方法:control()group()array() 。這些方法都是工廠方法,用於在元件類別中分別產生FormControlFormGroupFormArray

看下例示範:
test.component.ts

<pre class="brush:js;toolbar:false;">import { Component } from &amp;#39;@angular/core&amp;#39;; // 1、导入 FormBuilder import { FormBuilder, Validators } from &amp;#39;@angular/forms&amp;#39;; @Component({ selector: &amp;#39;app-test&amp;#39;, templateUrl: &amp;#39;./test.component.html&amp;#39;, styleUrls: [&amp;#39;./test.component.css&amp;#39;] }) export class TestComponent { // 2、注入 FormBuilder 服务 constructor(private fb: FormBuilder) { } ngOnInit() { } profileForm = this.fb.group({ firstName: [&amp;#39;&amp;#39;, [Validators.required, Validators.pattern(&amp;#39;[a-zA-Z0-9]*&amp;#39;)]], lastName: [&amp;#39;&amp;#39;, Validators.required], }); // 相当于 // profileForm = new FormGroup({ // firstName: new FormControl(&amp;#39;&amp;#39;, [Validators.required,Validators.pattern(&amp;#39;[a-zA-Z0-9]*&amp;#39;)]), // lastName: new FormControl(&amp;#39;&amp;#39;, Validators.required), // }); onSubmit() { console.log(this.profileForm.value) console.log(this.profileForm) } }</pre>比較可以發現,使用

FormBuilder

服務可以更方便地生成FormControlFormGroupFormArray,而不必每次都手動new一個新的實例出來。

表單驗證器Validators

#Validators

類別驗證器的完整API列表,參考API手冊:# https://angular.cn/api/forms/Validators

驗證器(
Validators

)函數可以是同步函數,也可以是非同步函數。 <ul> <li>同步验证器:这些同步函数接受一个控件实例,然后返回一组验证错误或 null。你可以在实例化一个 <code>FormControl 时把它作为构造函数的第二个参数传进去。

  • 异步验证器 :这些异步函数接受一个控件实例并返回一个 PromiseObservable,它稍后会发出一组验证错误或 null。在实例化 FormControl 时,可以把它们作为第三个参数传入。
  • 出于性能方面的考虑,只有在所有同步验证器都通过之后,Angular 才会运行异步验证器。当每一个异步验证器都执行完之后,才会设置这些验证错误。

    验证器Validators类的API

    https://angular.cn/api/forms/Validators

    class Validators {
      static min(min: number): ValidatorFn		// 允许输入的最小数值
      static max(max: number): ValidatorFn		// 最大数值
      static required(control: AbstractControl): ValidationErrors | null	// 是否必填
      static requiredTrue(control: AbstractControl): ValidationErrors | null
      static email(control: AbstractControl): ValidationErrors | null	// 是否为邮箱格式
      static minLength(minLength: number): ValidatorFn		// 最小长度
      static maxLength(maxLength: number): ValidatorFn		// 最大长度
      static pattern(pattern: string | RegExp): ValidatorFn	// 正则匹配
      static nullValidator(control: AbstractControl): ValidationErrors | null	// 什么也不做
      static compose(validators: ValidatorFn[]): ValidatorFn | null
      static composeAsync(validators: AsyncValidatorFn[]): AsyncValidatorFn | null
    }

    内置验证器函数

    要使用内置验证器,可以在实例化FormControl控件的时候添加

    import { Validators } from &#39;@angular/forms&#39;;
    ...
    ngOnInit(): void {
      this.heroForm = new FormGroup({
      // 实例化 FormControl 控件
        name: new FormControl(this.hero.name, [
          Validators.required,	// 验证,必填
          Validators.minLength(4),	// 长度不小于4
          forbiddenNameValidator(/bob/i) // 自定义验证器
        ]),
        alterEgo: new FormControl(this.hero.alterEgo),
        power: new FormControl(this.hero.power, Validators.required)
      });
    }
    get name() { return this.heroForm.get(&#39;name&#39;); }
    
    get power() { return this.heroForm.get(&#39;power&#39;); }

    自定义验证器

    自定义验证器的内容请参考 API手册:

    https://angular.cn/guide/form-validation

    有时候内置的验证器并不能很好的满足需求,比如,我们需要对一个表单进行验证,要求输入的值只能为某一个数组中的值,而这个数组中的值是随程序运行实时改变的,这个时候内置的验证器就无法满足这个需求,需要创建自定义验证器。

    • 在响应式表单中添加自定义验证器。在上面内置验证器一节中有一个forbiddenNameValidator函数如下:

      import { Validators } from &#39;@angular/forms&#39;;
      ...
      ngOnInit(): void {
        this.heroForm = new FormGroup({
          name: new FormControl(this.hero.name, [
            Validators.required,
            Validators.minLength(4),
            // 1、添加自定义验证器
            forbiddenNameValidator(/bob/i)
          ])
        });
      }
      // 2、实现自定义验证器,功能为禁止输入带有 bob 字符串的值
      export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
        return (control: AbstractControl): ValidationErrors | null => {
          const forbidden = nameRe.test(control.value);
          // 3、在值有效时返回 null,或无效时返回验证错误对象
          return forbidden ? {forbiddenName: {value: control.value}} : null;
        };
      }

      验证器在值有效时返回 null,或无效时返回验证错误对象。 验证错误对象通常有一个名为验证秘钥(forbiddenName)的属性。其值为一个任意词典,你可以用来插入错误信息({name})。

    • 在模板驱动表单中添加自定义验证器。要为模板添加一个指令,该指令包含了 validator 函数。同时,该指令需要把自己注册成为NG_VALIDATORS的提供者。如下所示:

      // 1、导入相关类
      import { NG_VALIDATORS, Validator, AbstractControl, ValidationErrors } from &#39;@angular/forms&#39;;
      import { Input } from &#39;@angular/core&#39;
      
      @Directive({
        selector: &#39;[appForbiddenName]&#39;,
        // 2、注册成为 NG_VALIDATORS 令牌的提供者
        providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
      })
      export class ForbiddenValidatorDirective implements Validator {
        @Input(&#39;appForbiddenName&#39;) forbiddenName = &#39;&#39;;
        // 3、实现 validator 接口,即实现 validate 函数
        validate(control: AbstractControl): ValidationErrors | null {
        	// 在值有效时返回 null,或无效时返回验证错误对象
          return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, &#39;i&#39;))(control)
                                    : null;
        }
      }
      // 4、自定义验证函数
      export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
        return (control: AbstractControl): ValidationErrors | null => {
          const forbidden = nameRe.test(control.value);
          // 3、在值有效时返回 null,或无效时返回验证错误对象
          return forbidden ? {forbiddenName: {value: control.value}} : null;
        };
      }

      注意,自定义验证指令是用 useExisting 而不是 useClass 来实例化的。如果用useClass来代替 useExisting,就会注册一个新的类实例,而它是没有forbiddenName 的。

      <input type="text" required appForbiddenName="bob" [(ngModel)]="hero.name">

    更多编程相关知识,请访问:编程视频!!

    以上是一文聊聊angular中的響應式表單的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除