如何在 Angular 中使用响应式表单

简介: 如何在 Angular 中使用响应式表单

简介

Angular 提供了两种处理表单的方式:模板驱动表单响应式表单(也称为 模型驱动表单)。模板驱动表单是在 Angular 中处理表单的默认方式。使用模板驱动表单时,模板指令被用来构建表单的内部表示。而使用响应式表单时,你需要在组件类中构建自己的表单表示。

以下是响应式表单的一些优势:

  • 使用自定义验证器
  • 动态改变验证规则
  • 动态添加表单字段

在本文中,你将探索如何将响应式表单应用到一个示例 Angular 应用程序中。

先决条件

如果你想跟着本文操作,你需要:

  • 本地安装 Node.js,你可以按照《如何安装 Node.js 并创建本地开发环境》进行操作。

本文假设你具有一些 Angular 的基础知识。

本文还假设你是在使用 @angular/cli 生成的全新 Angular 项目进行构建。如果你刚开始使用 Angular CLI,你可以参考本文。

本教程经过 Node v15.1.0、npm v6.14.8、@angular/core v11.0.0 和 @angular/forms v11.0.0 的验证。

步骤 1 —— 设置项目

为了本教程的目的,你将从使用 @angular/cli 生成的默认 Angular 项目开始构建。

npx @angular/cli new angular-reactive-forms-example --style=css --routing=false --skip-tests

这将配置一个新的 Angular 项目,其中样式设置为 “CSS”(而不是 “Sass”、“Less” 或 “Stylus”),没有路由,并且跳过了测试。

进入新创建的项目目录:

cd angular-reactive-forms-example

为了使用响应式表单,你将使用 ReactiveFormsModule 而不是 FormsModule

在你的代码编辑器中打开 app.module.ts 并添加 ReactiveFormsModule

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

到此为止,你应该已经有了一个使用 ReactiveFormsModule 的新的 Angular 项目。

步骤 2 —— 向组件模板添加表单

使用响应式表单时,逻辑完全在组件类中声明。

在你的代码编辑器中打开 app.component.html 并添加以下代码:

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label>
      Name:
      <input formControlName="name" placeholder="Your name">
    </label>
  </div>
  <div>
    <label>
      Email:
      <input formControlName="email" placeholder="Your email">
    </label>
  </div>
  <div>
    <label>
      Message:
      <input formControlName="message" placeholder="Your message">
    </label>
  </div>
  <button type="submit">Send</button>
</form>

这段代码将创建一个包含三个字段(nameemailmessage)的表单。还将有一个标签为 “Send” 的 "submit" 按钮。在提交表单时,将调用 onSubmit(myForm) 方法。

让我们来分解一下:

  • formGroup:表单将在组件类中被视为 FormGroup,因此 formGroup 指令允许给表单组指定一个名称。
  • ngSubmit:这是在提交表单时触发的事件。
  • formControlName:每个表单字段应该有一个 formControlName 指令,其值将在组件类中使用。

到此为止,你应该已经有了一个使用表单的组件模板。

步骤 3 —— 构建组件类

接下来,在组件类中,你将定义 FormGroupFormGroup 内的各个 FormControl

如果在 newing FormControl 时提供了一个值,它将被用作字段的初始值。

注意 FormGroupFormControl 的名称与模板中使用的名称相同。还要注意你如何在 ngOnInit 生命周期钩子中初始化 FormGroup

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;
  ngOnInit() {
    this.myForm = new FormGroup({
      name: new FormControl('Sammy'),
      email: new FormControl(''),
      message: new FormControl('')
    });
  }
  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

在本教程中,onSubmit 方法实际上并没有将提交的表单值传递给任何外部服务或服务器。它用于展示你如何访问表单的有效性和 FormControl 的值。

到此为止,你可以编译你的应用程序并在 web 浏览器中打开它。在为 nameemailmessage 输入值并点击 Submit 后,控制台日志将显示这些值。

第四步 — 更新组件类以使用 FormBuilder

ngOnInit 中的表单构建可以使用 FormBuilder 辅助程序进行重写。这样可以避免对表单组和表单控件进行 newing

在代码编辑器中打开 app.component.ts,移除 FormControl 并用 FormBuilder 替换 FormGroup

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;
  constructor(private fb: FormBuilder) {}
  ngOnInit() {
    this.myForm = this.fb.group({
      name: 'Sammy',
      email: '',
      message: ''
    });
  }
  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

使用 FormBuilder 的这段代码减少了创建 FormGroup 的样板代码。

第五步 — 更新组件类以使用 Validators

Validators 类添加到你的导入中,并使用数组而不是简单的字符串值来声明表单控件。

数组中的第一个值是初始表单值,第二个值是要使用的验证器。请注意,可以通过将它们包装成数组来在同一个表单控件上使用多个验证器。

在代码编辑器中打开 app.component.ts,添加 Validators

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;
  constructor(private fb: FormBuilder) {}
  ngOnInit() {
    this.myForm = this.fb.group({
      name: ['Sammy', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      message: ['', [Validators.required, Validators.minLength(15)]],
    });
  }
  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

这段代码为 nameemailmessage 字段添加了 required。它还确保 email 值使用有效电子邮件地址的格式。它还确保 message 值至少为 15 个字符长。

如果这些表单要求中的任何一个未通过,valid 值将为 false。如果所有这些表单要求都通过,valid 值将为 true

第六步 — 在模板中访问表单值和有效性

在模板中,可以访问每个 FormControl 的值和有效性,以及整个表单组的值和有效性。

打开 app.component.html,使用 *ngIf 来显示反馈消息,告诉用户表单值无效:

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label>
      Name:
      <input formControlName="name" placeholder="Your name">
    </label>
    <div *ngIf="myForm.get('name').invalid && (myForm.get('name').dirty || myForm.get('name').touched)">
      Please provide a name.
    </div>
  </div>
  <div>
    <label>
      Email:
      <input formControlName="email" placeholder="Your email">
    </label>
    <div *ngIf="myForm.get('email').invalid && (myForm.get('email').dirty || myForm.get('email').touched)">
      Please provide a valid email address.
    </div>
  </div>
  <div>
    <label>
      Message:
      <input formControlName="message" placeholder="Your message">
    </label>
    <div *ngIf="myForm.get('message').invalid && (myForm.get('message').dirty || myForm.get('message').touched)">
      Messages must be at least 15 characters long.
    </div>
  </div>
  <button type="submit" [disabled]="myForm.invalid">Send</button>
</form>

这段代码检查用户是否与字段交互(dirtytouched)。然后,如果值未通过验证要求,它将显示错误消息。Send 按钮也将在解决表单值的所有问题之前被禁用。

有多种方法可以检索表单控件的值。此示例使用 myForm.get('name'),它等同于 myForm.controls.name。可以使用 .hasError('required').errors.required 检索错误信息。

结论

在本文中,您探讨了如何将响应式表单应用于一个示例 Angular 应用程序。您使用了 FormControlFormGroupFormBuilderValidators 来构建一个带有验证的示例表单。如需了解更多功能,请参考官方文档。

如果您想了解更多关于 Angular 的知识,请查看我们的 Angular 专题页面,了解相关练习和编程项目。


目录
相关文章
|
23天前
|
缓存 前端开发 JavaScript
前端serverless探索之组件单独部署时,利用rxjs实现业务状态与vue-react-angular等框架的响应式状态映射
本文深入探讨了如何将RxJS与Vue、React、Angular三大前端框架进行集成,通过抽象出辅助方法`useRx`和`pushPipe`,实现跨框架的状态管理。具体介绍了各框架的响应式机制,展示了如何将RxJS的Observable对象转化为框架的响应式数据,并通过示例代码演示了使用方法。此外,还讨论了全局状态源与WebComponent的部署优化,以及一些实践中的改进点。这些方法不仅简化了异步编程,还提升了代码的可读性和可维护性。
|
3月前
|
开发者 Java Spring
JSF 牵手社交登录,如魔法风暴席卷 Web 世界,开启震撼便捷登录之旅!
【8月更文挑战第31天】在互联网时代,便捷登录成为用户的核心需求。社交登录凭借其便捷性、安全性和社交化的特点,在各类Web应用中广泛应用。JavaServer Faces(JSF),作为一款流行的Java Web框架,能够轻松集成社交登录功能,显著提升用户体验。本文详细介绍社交登录的优势,并提供两种JSF集成社交登录的常见方法:一是利用Spring Social等第三方库简化开发;二是自行实现社交登录流程。开发者可根据项目需求选择适合的方案。
41 0
|
3月前
|
开发者 容器 Docker
JSF与Docker,引领容器化浪潮!让你的Web应用如虎添翼,轻松应对高并发!
【8月更文挑战第31天】在现代Web应用开发中,JSF框架因其实用性和灵活性被广泛应用。随着云计算及微服务架构的兴起,容器化技术变得日益重要,Docker作为该领域的佼佼者,为JSF应用提供了便捷的部署和管理方案。本文通过基础概念讲解及示例代码展示了如何利用Docker容器化JSF应用,帮助开发者实现高效、便携的应用部署。同时也提醒开发者注意JSF与Docker结合使用时可能遇到的限制,并根据实际情况做出合理选择。
41 0
|
3月前
|
前端开发 UED 开发者
深度剖析Angular表单控件:从模板驱动到响应式表单的最佳实践,带你全面掌握Angular表单处理机制,提升前端开发效率与用户体验的终极指南
【8月更文挑战第31天】本文通过代码示例详细介绍了 Angular 中两种主要的表单处理方式:模板驱动表单和响应式表单。模板驱动表单适用于简单场景,可在 HTML 模板中直接定义表单控件并实现数据绑定和验证。响应式表单基于 RxJS,提供更灵活的表单管理和复杂的逻辑处理。通过具体示例展示了每种方式的最佳实践,帮助开发者简化表单处理,提高开发效率和用户体验。
31 0
|
3月前
|
数据采集 前端开发 开发者
Angular表单控件详解:掌握模板驱动与响应式表单的精髓,让Web应用中的数据采集工作变得高效又简单,彻底告别繁琐的表单处理流程
【8月更文挑战第31天】表单是 Web 应用的关键组件,用于用户登录、注册及信息提交。Angular 作为成熟前端框架,提供了强大的表单处理功能,包括模板驱动与响应式表单。本文通过技术博客形式,详细介绍这两种表单控件,并提供示例代码,展示如何利用它们简化表单处理流程,提高开发效率。首先介绍简单的模板驱动表单,然后讲解基于 RxJS 的响应式表单,适用于复杂逻辑。通过本文,你将学会如何高效地使用 Angular 表单控件,提升应用的用户体验。
41 0
|
3月前
Angular 中的响应式表单:监听变化
Angular 中的响应式表单:监听变化
39 0
|
3月前
|
JavaScript 前端开发
如何在 Angular 中为响应式表单创建自定义验证器
如何在 Angular 中为响应式表单创建自定义验证器
25 0
|
3月前
|
JavaScript
如何使用 ControlValueAccessor 在 Angular 中创建自定义表单控件
如何使用 ControlValueAccessor 在 Angular 中创建自定义表单控件
22 0
|
前端开发 数据安全/隐私保护 CDN
Angular最新教程-第六节编写响应式导航栏
Angular最新教程-第六节编写响应式导航栏
417 0
Angular最新教程-第六节编写响应式导航栏
|
API
Angular 2.x折腾记 :(7) 初步了解表单:模板驱动及数据驱动及脱坑要点
表单在整个系统中的作用相当重要,这里主要扯下响应表单的实现方式。 首先需要操作表单的模块引入这两个模块; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
170 0