Angular 4.x 中有两种表单:

  • Template-Driven Forms - 模板驱动式表单 (类似于 AngularJS 1.x 中的表单 )  官方文档:https://v2.angular.cn/docs/ts/latest/guide/forms.html

  • Reactive Forms (Model-Driven Forms) - 响应式表单  官方文档: https://v2.angular.cn/docs/ts/latest/guide/reactive-forms.html

Template-Driven Forms vs Reactive Forms

Template-Driven Forms (模板驱动表单) 的特点

  • 使用方便

  • 适用于简单的场景

  • 通过 [(ngModel)] 实现数据双向绑定

  • 最小化组件类的代码

  • 不易于单元测试

  • 异步的,模板驱动表单会委托指令来创建它们的表单控件。 为了消除“检查完后又变化了”的错误,这些指令需要消耗一个以上的变更检测周期来构建整个控件树。 这意味着在从组件类中操纵任何控件之前,我们都必须先等待一个节拍。

Reactive Forms (响应式表单) 的特点

  • 比较灵活

  • 适用于复杂的场景

  • 简化了HTML模板的代码,把验证逻辑抽离到组件类中

  • 方便的跟踪表单控件值的变化

  • 易于单元测试

  • 同步的 ,使用响应式表单,我们会在代码中创建整个表单控件树。 我们可以立即更新一个值或者深入到表单中的任意节点,因为所有的控件都始终是可用的。

使用 reactive forms 表单前,我们必须在 @NgModule 中导入 @angular/forms 库中的 ReactiveFormsModule

import { ReactiveFormsModule } from '@angular/forms';@NgModule({imports: [...,ReactiveFormsModule],declarations: [...],bootstrap: [...]
})
export class AppModule {}

友情提示:若使用 reactive forms,则导入 ReactiveFormsModule;若使用 template-driven 表单,则导入 FormsModule。

FormControl 和 FormGroup

FormControl - 它是一个为单个表单控件提供支持的类,可用于跟踪控件的值和验证状态,此外还提供了一系列公共API。

使用示例:

ngOnInit() {this.myControl = new FormControl('Semlinker');
}

FormGroup - 包含是一组 FormControl 实例,可用于跟踪 FormControl 组的值和验证状态,此外也提供了一系列公共API。

使用示例:

ngOnInit() {this.myGroup = new FormGroup({name: new FormControl('Semlinker'),location: new FormControl('China, CN')});
}

现在我们已经创建了 FormControl 和 FormGroup 实例,接下来我们来看一下如何使用:

<form novalidate [formGroup]="myGroup">Name: <input type="text" formControlName="name">Location: <input type="text" formControlName="location">
</form>

注意事项:Template-Driven Forms 中介绍的 ngModel 和 name="" 属性,已经被移除了。这是一件好事,让我们的模板更简洁。

上面示例中,我们必须使用 [formGroup] 绑定我们创建的 myGroup 对象,除此之外还要使用 formControlName 指令,绑定我们创建的 FormControl 控件。此时的表单结构如下:

FormGroup -> 'myGroup'FormControl -> 'name'FormControl -> 'location'

User interface

signup.interface.ts

export interface User {name: string;account: {email: string;confirm: string;}
}

与之对应的表单结构如下:

FormGroup -> 'user'FormControl -> 'name'FormGroup -> 'account'FormControl -> 'email'FormControl -> 'confirm'

是的,我们可以创建嵌套的 FormGroup 集合!让我们更新一下组件 (不包含初始数据):

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';@Component({...})
export class SignupFormComponent implements OnInit {user: FormGroup;ngOnInit() {this.user = new FormGroup({name: new FormControl(''),account: new FormGroup({email: new FormControl(''),confirm: new FormControl('')})});}
}

如果我们想要设置初始数据,我们可以按照上述示例进行设置。通常情况下,我们通过服务端提供的 API 接口来获取表单的初始信息。

绑定FormGroup模型

<form novalidate [formGroup]="user"><label><span>Full name</span><inputtype="text"placeholder="Your full name"formControlName="name"></label><div formGroupName="account"><label><span>Email address</span><inputtype="email"placeholder="Your email address"formControlName="email"></label><label><span>Confirm address</span><inputtype="email"placeholder="Confirm your email address"formControlName="confirm"></label></div><button type="submit">Sign up</button>
</form>

现在 FormGroup 与 FormControl 对象与 DOM 结构的关联信息如下:

// JavaScript APIs
FormGroup -> 'user'FormControl -> 'name'FormGroup -> 'account'FormControl -> 'email'FormControl -> 'confirm'// DOM bindings
formGroup -> 'user'formControlName -> 'name'formGroupName -> 'account'formControlName -> 'email'formControlName -> 'confirm'

当使用模板驱动的表单时,为了获取 f.value 表单的值,我们需要先执行 #f="ngForm" 的操作。而对于使用响应式的表单,我们可以通过以下方式,方便的获取表单的值:

{{ user.value | json }} // { name: '', account: { email: '', confirm: '' }}

Reactive submit

跟模板驱动的表单一样,我们可以通过 ngSubmit 输出属性,处理表单的提交逻辑:

<form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user">...
</form>

需要注意的是,我们使用 user 对象作为 onSubmit() 方法的参数,这使得我们可以获取表单对象的相关信息,具体处理逻辑如下:

export class SignupFormComponent {user: FormGroup;onSubmit({ value, valid }: { value: User, valid: boolean }) {console.log(value, valid);}
}

上面代码中,我们使用 Object destructuring (对象解构) 的方式,从user 对象中获取 value 和 valid 属性的值。其中 value的值,就是 user.value 的值。在实际应用中,我们是不需要传递 user 参数的:

export class SignupFormComponent {user: FormGroup;onSubmit() {console.log(this.user.value, this.user.valid);}
}

表单的数据绑定方式和提交逻辑已经介绍完了,是该介绍表单实际应用中,一个重要的环节 — 表单验证。

Reactive error validation

接下来我们来为表单添加验证规则,首先我们需要从 @angular/forms 中导入 Validators。具体使用示例如下:

ngOnInit() {this.user = new FormGroup({name: new FormControl('', [Validators.required, Validators.minLength(2)]),account: new FormGroup({email: new FormControl('', Validators.required),confirm: new FormControl('', Validators.required)})});
}

通过以上示例,我们可以看出,如果表单控制包含多种验证规则,可以使用数组声明多种验证规则。若只包含一种验证规则,直接声明就好。通过这种方式,我们就不需要在模板的输入控件中添加 required 属性。接下来我们来添加表单验证失败时,不允许进行表单提交功能:

<form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user">...<button type="submit" [disabled]="user.invalid">Sign up</button>
</form>

那么问题来了,我们要如何获取表单控件的验证信息?我们可以使用模板驱动表单中介绍的方式,具体如下:

<form novalidate [formGroup]="user">{{ user.controls.name?.errors | json }}
</form>

友情提示:?.prop 称为安全导航操作符,用于告诉 Angular prop 的值可能不存在。

此外我们也可以使用 FormGroup 对象提供的 API,来获取表单控件验证的错误信息:

<form novalidate [formGroup]="user">{{ user.get('name').errors | json }}
</form>

完整代码:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { User } from './signup.interface';
@Component({selector: 'signup-form',template: `<form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user"><label><span>Full name</span><input type="text" placeholder="Your full name" formControlName="name"></label><div class="error" *ngIf="user.get('name').hasError('required') && user.get('name').touched">Name is required</div><div class="error" *ngIf="user.get('name').hasError('minlength') && user.get('name').touched">Minimum of 2 characters</div><div formGroupName="account"><label><span>Email address</span><input type="email" placeholder="Your email address" formControlName="email"></label><divclass="error"*ngIf="user.get('account').get('email').hasError('required') && user.get('account').get('email').touched">Email is required</div><label><span>Confirm address</span><input type="email" placeholder="Confirm your email address" formControlName="confirm"></label><divclass="error"*ngIf="user.get('account').get('confirm').hasError('required') && user.get('account').get('confirm').touched">Confirming email is required</div></div><button type="submit" [disabled]="user.invalid">Sign up</button></form>`
})
export class SignupFormComponent implements OnInit {user: FormGroup;constructor() {}ngOnInit() {this.user = new FormGroup({name: new FormControl('', [Validators.required, Validators.minLength(2)]),account: new FormGroup({email: new FormControl('', Validators.required),confirm: new FormControl('', Validators.required)})});}onSubmit({ value, valid }: { value: User, valid: boolean }) {console.log(value, valid);}
}

功能是实现了,但创建 FormGroup 对象的方式有点繁琐,Angular 团队也意识到这点,因此为我们提供 FormBuilder ,来简化上面的操作。

Simplifying with FormBuilder

首先我们需要从 @angular/forms 中导入 FormBuilder

import { FormBuilder, FormGroup, Validators } from '@angular/forms';export class SignupFormComponent implements OnInit {user: FormGroup;constructor(private fb: FormBuilder) {}...
}

使用FormBuilder:

@Component({...})
export class SignupFormComponent implements OnInit {user: FormGroup;constructor(private fb: FormBuilder) {}ngOnInit() {this.user = this.fb.group({name: ['', [Validators.required, Validators.minLength(2)]],account: this.fb.group({email: ['', Validators.required],confirm: ['', Validators.required]})});}onSubmit({ value, valid }: { value: User, valid: boolean }) {console.log(value, valid);}
}

转自:https://segmentfault.com/a/1190000009041192

转载于:https://www.cnblogs.com/xuepei/p/7922022.html

Angular Reactive Forms -- Model-Driven Forms响应式表单相关推荐

  1. Angular 响应式表单 patchValue和setValue

    在 Angular 4 中有多种方式可以更新表单的值,对于使用响应式表单的场景,我们可以通过框架内部提供的 API ,(如 patchValue 和 setValue )方便地更新表单的值.这篇文章我 ...

  2. Angular响应式表单及表单验证

    1. 什么是响应式表单? 响应式表单提供了一种模型驱动的方式来处理表单输入,其中的值会随时间而变化. 响应式表单使用显示的,不可变的方式,管理表单在特定时间点上的状态.对表单状态的每一次变更都会返回一 ...

  3. Angular中响应式表单 FormBuilder、FormControl 、FormGroup、FormArray、setControl、setValue用法总结

    以我的项目作为示例,总结一下Angular响应式表单的应用和常用的方法: 1.创建表单 form.ts代码 import { Component, OnInit } from "@angul ...

  4. Angular 响应式表单 基础例子

    1.案例需求 表单提交,表单全部校验成功才能提交,当表单校验错误,表单边框变红,同时有错误提示信息,有重置功能 2.代码分析 在线预览 git仓库 本案例中使用了响应式表单,响应式表单在表单的校验方面 ...

  5. 灵雀云前端: Angular 响应式表单

    Kubernetes 对象实战 简介 Kubernetes 集群的使用者日常工作中经常需要与 Deployment 等 Kubernetes 对象接触.熟悉 Kubernetes 的朋友都会知道,Ku ...

  6. Angular 响应式表单

    Kubernetes 对象实战 简介 Kubernetes 集群的使用者日常工作中经常需要与 Deployment 等 Kubernetes 对象接触.熟悉 Kubernetes 的朋友都会知道,Ku ...

  7. Angular2响应式表单

    本文将半翻译半总结的讲讲ng2官网的另一个未翻译高级教程页面. 原文地址. 文章目的是使用ng2提供的响应式表单技术快速搭出功能完善丰富的界面表单组件. 响应式表单是一项响应式风格的ng2技术,本文将 ...

  8. angular6的响应式表单

    1:在AppModule模块里面引入 ReactiveFormsModule 要使用响应式表单,就要从@angular/forms包中导入ReactiveFormsModule,并把它添加到你的NgM ...

  9. angularjs 表单校验指令_angular4.0的模板式表单、响应式表单及其错误提示

    模板式表单 NgForm.NgModel.NgModelGroup是FormModule里的内容,NgForm会自动拦截标准的表单处理事件(eg.提交),angular用ngSubmit代替标准的表单 ...

最新文章

  1. MXNet动手学深度学习笔记:卷积计算
  2. dependencyManagement与dependencies区别
  3. oracle 使从表中随机取出一行记录数据
  4. Unity 白猫操作小实例
  5. [转载] StringBuffer和StringBuilder类
  6. 动漫App下载单页界面HTML源码带弹幕
  7. python3高级 一 迭代器
  8. 无人驾驶的规划与控制(一)——路由寻径
  9. CentOS 7下无法启动网络(service network start)错误解决办法(转)
  10. react调用api等待返回结果_React新Context API在前端状态管理的实践
  11. 分享Java 中如何运行字符串表达式?
  12. 学习笔记_2011-10-02
  13. java.lang.InternalError: internal error: SHA-1 not available.
  14. 翻译:MySQL Got an Error Reading Communication Packet Errors
  15. c语言经典100例对考研有用吗,考研数学经验,没用算这学长输
  16. 【附干货】卸载CAD后将注册表清理干净的方法及步骤
  17. echart 迁徙图
  18. 自动控制原理学习--奈奎斯特稳定判据
  19. c 语言len函数,巧妙利用LEN、SUBSTITUTE函数,计算EXCEL单元格内某重复字符个数
  20. 中国动感单车行业销售模式与营销渠道预测报告2021-2026年

热门文章

  1. 记录spring、springboot集成apollo配置中心
  2. mysql 读取properties_JDBC中使用Properties读取配置文件有什么用
  3. Spring —— 容器内部逻辑
  4. account表里有什么 银行_模拟一个银行账户类Account,账户类中包括所有者、账号、余额、账户总数、存款、取款等信息。_学小易找答案...
  5. 从sqlite 迁移 mysql_将 Ghost 从 SQLite3 数据库迁移到 MySQL 数据库
  6. linux include 编译,linux-如何使用OpenSSL include编译.c文件?
  7. axure 小程序 lib_使用maven和fat jar/war运行应用程序的对比
  8. C语言数组元素的查询
  9. sql 成功率_备考2022年MBA: 如何提高清华、北大MBA提前面试成功率|博雅汇MBA
  10. python实例 65,66