官网地址:https://angular.cn/guide/forms-overview
目录
一、表单简介
1.Angular提供了两种不同的方法来通过表单处理用户输入:响应式表单和模板驱动表单。两者都从视图中捕获用户输入事件、验证用户输入、创建表单模型、修改数据模型、并提供跟踪这些更改的途径。
不过,响应式表单和模板驱动表单在如何处理和管理表单和表单数据方面有所不同。各有优势。
一般来说:
-
响应式表单更健壮:它们的可扩展性、可复用性和可测试性更强。 如果表单是应用中的关键部分,或者你已经准备使用响应式编程模式来构建应用,请使用响应式表单。
-
模板驱动表单在往应用中添加简单的表单时非常有用,比如邮件列表的登记表单。它们很容易添加到应用中,但是不像响应式表单那么容易扩展。如果你有非常基本的表单需求和简单到能用模板管理的逻辑,请使用模板驱动表单。
-
下表总结了响应式表单和模板驱动表单之间的一些关键差异。
响应式
模板驱动
建立(表单模式)
显式,在组件类中创建。
隐式,由组件创建。
数据模式
结构化
非结构化
可预测性
同步
异步
表单验证
函数
指令
可变性
不可变
可变
可伸缩性
访问底层 API
在 API 之上的抽象
共同基础
响应式表单和模板驱动表单共享了一些底层构造块。
-
FormControl
实例用于追踪单个表单控件的值和验证状态。 -
FormGroup
用于追踪一个表单控件组的值和状态。 -
FormArray
用于追踪表单控件数组的值和状态。 -
ControlValueAccessor
用于在 Angular 的FormControl
实例和原生 DOM 元素之间创建一个桥梁。
权威数据源负责提供在指定时间点上表单元素的值和状态。在响应式表单中,表单模式充当权威数据源。上例中的表单模型就是 FormControl
的实例。
建立表单模型
响应式表单和模板驱动表单都是用表单模型来跟踪 Angular 表单和表单输入元素之间值的变化。下面的例子展示了如何定义和创建表单模型。
在响应式表单中建立
下面是一个带有输入字段的组件,它使用响应式表单实现了单个控件。
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-reactive-favorite-color',
template: `
Favorite Color: <input type="text" [formControl]="favoriteColorControl">
`
})
export class FavoriteColorComponent {
favoriteColorControl = new FormControl('');
}
权威数据源负责提供在指定时间点上表单元素的值和状态。在响应式表单中,表单模式充当权威数据源。上例中的表单模型就是 FormControl
的实例。
在响应式表单中,表单模型是显式定义在组件类中的。接着,响应式表单指令(这里是 FormControlDirective
)会把这个现有的表单控件实例通过数据访问器(ControlValueAccessor
的实例)来指派给视图中的表单元素。
在模板驱动表单中建立
下面是同一个带有输入字段的组件,它使用模板驱动表单实现了单个控件。
import { Component } from '@angular/core';
@Component({
selector: 'app-template-favorite-color',
template: `
Favorite Color: <input type="text" [(ngModel)]="favoriteColor">
`
})
export class FavoriteColorComponent {
favoriteColor = '';
}
在模板驱动表单中,权威数据源是模板。
表单模型的抽象促进了结构的简化。模板驱动表单的 NgModel
指令负责创建和管理指定表单元素上的表单控件实例。它不那么明显,但你不必再直接操纵表单模型了。
表单中的数据流
当在 Angular 中构建表单时,理解框架如何处理来自用户或程序化修改的数据流是非常重要的。 在处理表单输入时,响应式表单和模板驱动表单遵循两种不同的策略。下面的数据流范例从以前的 "喜欢的颜色" 输入框开始,展示了它在响应式表单中的工作方式与模板驱动表单相比有何不同。
响应式表单中的数据流
如前所述,在响应式表单中,视图中的每个表单元素都直接链接到一个表单模型(FormControl
实例)。 从视图到模型的修改以及从模型到视图的修改都是同步的,不依赖于所呈现的 UI。下面的图示使用了同一个 "喜欢的颜色" 范例,来演示当输入字段的值的变更来自视图和来自模型时,数据如何流动。
下面这些步骤列出了 "从视图到模型" 数据流的梗概。
-
最终用户在输入框元素中键入了一个值,这里是 "Blue"。
-
这个输入框元素会发出一个带有最新值的 "input" 事件。
-
这个控件值访问器
ControlValueAccessor
会监听表单输入框元素上的事件,并立即把新值传给FormControl
实例。 -
FormControl
实例会通过valueChanges
这个可观察对象发出这个新值。 -
valueChanges
的任何一个订阅者都会收到这个新值。
下面这些步骤列出了从模型到视图的数据流的梗概。
-
favoriteColorControl.setValue()
方法被调用,它会更新这个FormControl
的值。 -
FormControl
实例会通过valueChanges
这个可观察对象发出新值。 -
valueChanges
的任何订阅者都会收到这个新值。 -
该表单输入框元素上的控件值访问器会把控件更新为这个新值。
模板驱动表单中的数据流
在模板驱动表单中,每个表单元素都链接到一个指令上,该指令负责管理其内部表单模型。下图使用相同的 "喜欢的颜色" 示例来演示当输入字段的值的变更来自视图和来自模板时,数据如何流动。
下面这些步骤列出了当输入框的值从 Red 变成 Blue 时 "从视图到模型" 的数据流概况。
-
最终用户在输入框元素中敲 "Blue"。
-
该输入框元素会发出一个 "input" 事件,带着值 "Blue"。
-
附着在该输入框上的控件值访问器会触发
FormControl
实例上的setValue()
方法。 -
FormControl
实例通过valueChanges
这个可观察对象发出新值。 -
valueChanges
的任何订阅者都会收到新值。 -
控件值访问器
ControlValueAccessory
还会调用NgModel.viewToModelUpdate()
方法,它会发出一个ngModelChange
事件。 -
由于该组件模板双向数据绑定到了
favoriteColor
,组件中的favoriteColor
属性就会修改为ngModelChange
事件所发出的值("Blue")。
下面这些步骤列出了当 favoriteColor
从 Blue 变为 Red 时,"从模型到视图" 的数据流概况。
-
组件中修改了
favoriteColor
的值。 -
变更检测开始。
-
在变更检测期间,由于这些输入框之一的值发生了变化,Angular 就会调用
NgModel
指令上的ngOnChanges
生命周期钩子。 -
ngOnChanges()
方法会把一个异步任务排入队列,以设置内部FormControl
实例的值。 -
变更检测完成。
-
在下一个检测周期,用来为
FormControl
实例赋值的任务就会执行。 -
FormControl
实例通过可观察对象valueChanges
发出最新值。 -
valueChanges
的任何订阅者都会收到这个新值。 -
控件值访问器
ControlValueAccessor
会使用favoriteColor
的最新值来修改表单的输入框元素。
表单验证
验证是管理任何表单时必备的一部分。无论你是要检查必填项,还是查询外部 API 来检查用户名是否已存在,Angular 都会提供一组内置的验证器,以及创建自定义验证器所需的能力。
-
响应式表单把自定义验证器定义成函数,它以要验证的控件作为参数。
-
模板驱动表单和模板指令紧密相关,并且必须提供包装了验证函数的自定义验证器指令。
实践
在使用响应式表单的时候,报错如下:
因为在理论学习的过程中了解到了,对于响应式表单而言,为表单控件添加 formControl
绑定,formControl
是由 ReactiveFormsModule
中的 FormControlDirective
提供的。
并且官网中明确说明了:要使用响应式表单,就要从 @angular/forms
包中导入 ReactiveFormsModule
并把它添加到你的 NgModule 的 imports
数组中。
因此,需要在在app.module.ts中引入即可。
来源:CSDN
作者:Delicia_Lani
链接:https://blog.csdn.net/qq_29918313/article/details/103763198