Angular实现响应式表单


Posted in Javascript onAugust 04, 2017

介绍

Angular 总共提供了 3 中表单实现方式,分别是:Template-driven Forms (模板驱动表单) 、 Reactive Forms (响应式表单) 、 Dynamic Forms (动态表单) 。本文只介绍响应式表单。

响应式表单是什么呢?其实跟我们以前用 JQuery 或者其他框架实现的思路差不多,就是使用 HTML 显示数据,然后通过定义一定的校验器、校验规则以及校验提示语,通过事件触发校验后校验不通过的显示提示语,只不过用了 Angular,我们就使用 Angular 提供的语法来实现这个校验过程。

使用

接下来我们通过代码例子来介绍如何使用响应式表单。

引入响应式表单模块

在我们要使用响应式表单的那个模块里面引入响应式表单模块,比如我们在文章模块中使用响应式表单,我们就要在 imports 中添加 ReactiveFormsModule。代码如下

@NgModule({
 imports: [
 RouterModule,
 RouterModule.forChild(articleRoutes),
 SharedModule,
 ReactiveFormsModule,
 NgbModule.forRoot()
 ],
 declarations: [
 HomeComponent,
 DetailComponent,
 CommentComponent,
 CommentViewComponent
 ],
 providers: [
 HomeService,
 DetailService,
 CommentService
 ]
})
export class ArticleModule { }

编写校验器代码

首先我们这里的表单有 3 个字段,分别是 nickname、email、content; nickname 添加必填校验器,email 添加必填和邮箱格式校验器,content添加必填校验器。

首先在 CommentComponent 中注入 FormBuilder 对象,并添加 commentForm 表单组以及创建一个评论对象 comment。

public commentForm: FormGroup;
public comment: Comment = new Comment();

constructor(private formBuilder: FormBuilder){}

定义校验器的提示语 validationMessages, formErrors 是在模板中显示的提示语,提示语来自 validationMessages

public formErrors = {
 "nickname": "",
 "email": "",
 "content": "",
 "formError": ""
}

public validationMessages = {
 "nickname": {
 "required": "昵称不能为空",
 },
 "email": {
 "required": "邮箱不能为空",
 "pattern": "请输入正确的邮箱地址"
 },
 "content": {
 "required": "内容不能为空"
 }
}

在组件启动的函数中构造表单,这时候为每个字段添加了校验器,并且绑定在什么时候触发校验,这里我们在每个值改变的时候触发。

ngOnInit(): void {
 this.buildForm();
}

private buildForm() {
 this.commentForm = this.formBuilder.group({
 "nickname":[
  this.comment.nickname,
  [
  Validators.required
  ]
 ],
 "email": [
  this.comment.email,
  [
  Validators.required,
  Validators.pattern("^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$")
  ]
 ],
 "content": [
  this.comment.content,
  [
  Validators.required
  ]
 ]
 });
 this.commentForm.valueChanges.subscribe(data => this.onValueChanged(data));
 this.onValueChanged();
}

onValueChanged() 方法实现了判断是那个字段校验不通过,然后将该字段的 validationMessages 提示语赋值给 formErrors,在模板那里有判断如果 formErrors.email 等等字段不为空则显示改内容,也即是校验器的提示语

onValueChanged(data?: any) {
 if (!this.commentForm) {
 return;
 }
 const form = this.commentForm;
 for (const field in this.formErrors) {
 this.formErrors[field] = '';
 const control = form.get(field);
 if (control && control.dirty && !control.valid) {
  const messages = this.validationMessages[field];
  for (const key in control.errors) {
  this.formErrors[field] += messages[key] + ' ';
  }
 }
 }

}

HTML 模板代码

我们要关注的是 [formGroup]=”commentForm”、novalidate、formControlName=”nickname”、以及 *ngIf=”formErrors.nickname” 这几个点,并不是指具体的点,而是着重看这些语法的每一个地方,在你自己实现的时候需要根据你的代码修改的。

还有一个是 (ngSubmit)=”sendComment()” 定义了该表单点击提交时调用的函数。

<form [formGroup]="commentForm" (ngSubmit)="sendComment()" role="form" novalidate>
 <div class="control-group">
 <div class="form-group floating-label-form-group controls" [ngClass]="{'has-error': formErrors.nickname}">
  <label>{{ 'comment.nickname' | translate }}</label>
  <input formControlName="nickname" type="text" class="form-control" placeholder="{{ 'comment.nickname' | translate }}">
  <p *ngIf="formErrors.nickname" class="help-block text-danger">
  {{ formErrors.nickname }}
  </p>
 </div>
 </div>
 <div class="control-group" >
 <div class="form-group floating-label-form-group controls" [ngClass]="{'has-error': formErrors.email}">
  <label>{{ 'comment.email' | translate }}</label>
  <input formControlName="email" type="email" class="form-control" placeholder="{{ 'comment.email' | translate }}">
  <p *ngIf="formErrors.email" class="help-block text-danger">
  {{ formErrors.email }}
  </p>
 </div>
 </div>
 <div class="control-group">
 <div class="form-group floating-label-form-group controls" [ngClass]="{'has-error': formErrors.content}">
  <label>{{ 'comment.content' | translate }}</label>
  <textarea formControlName="content" rows="5" class="form-control" placeholder="{{ 'comment.content' | translate }}"></textarea>
  <p *ngIf="formErrors.content" class="help-block text-danger">
  {{ formErrors.content }}
  </p>
 </div>
 </div>
 <p *ngIf="formErrors.formError" class="help-block text-danger">
 {{ formErrors.formError }}
 </p>
 <br>
 <div id="success"></div>
 <div class="form-group">
 <button [disabled]="commentForm.invalid" type="submit" class="btn btn-secondary" >{{ 'comment.submit' | translate }}</button>
 </div>
</form>

GitHub 代码

参考文章

Reactive Forms

效果图

Angular实现响应式表单

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript原型模式用法实例详解
Jun 04 Javascript
javascript实现tab切换的四种方法
Nov 05 Javascript
谈谈jQuery Ajax用法详解
Nov 27 Javascript
JS实现的自定义水平滚动字体插件完整实例
Jun 17 Javascript
JavaScript实现获取用户单击body中所有A标签内容的方法
Jun 05 Javascript
微信小程序实现上传图片功能
May 28 Javascript
layui中table表头样式修改方法
Aug 15 Javascript
iview通过Dropdown(下拉菜单)实现的右键菜单
Oct 26 Javascript
Vue-cli3.x + axios 跨域方案踩坑指北
Jul 04 Javascript
微信小程序实现Swiper轮播图效果
Nov 22 Javascript
javascript实现前端分页效果
Jun 24 Javascript
原生js实现俄罗斯方块
Oct 20 Javascript
JS 实现banner图片轮播效果(鼠标事件)
Aug 04 #Javascript
jQuery选取所有复选框被选中的值并用Ajax异步提交数据的实例
Aug 04 #jQuery
JavaScript正则表达式校验与递归函数实际应用实例解析
Aug 04 #Javascript
js模拟百度模糊搜索的实例
Aug 04 #Javascript
JavaScript模拟文件拖选框样式v1.0的实例
Aug 04 #Javascript
addeventlistener监听scroll跟touch(实例讲解)
Aug 04 #Javascript
原生js jquery ajax请求以及jsonp的调用方法
Aug 04 #jQuery
You might like
php的zip解压缩类pclzip使用示例
2014/03/14 PHP
PHP闭包定义与使用简单示例
2018/04/13 PHP
详解PHP素材图片上传、下载功能
2019/04/12 PHP
PHP-FPM 设置多pool及配置文件重写操作示例
2019/10/02 PHP
javascript 子窗体父窗体相互传值方法
2010/05/31 Javascript
jQuery学习笔记之jQuery动画效果
2013/09/09 Javascript
javascript教程之不完整的继承(js原型链)
2014/01/13 Javascript
详谈JavaScript 匿名函数及闭包
2014/11/14 Javascript
页面内容排序插件jSort使用方法
2015/10/10 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
2016/06/13 Javascript
jQuery插件Validation快速完成表单验证的方式
2016/07/28 Javascript
功能强大的Bootstrap使用手册(一)
2016/08/02 Javascript
配置nodejs环境的方法
2017/05/13 NodeJs
Vue-cli创建项目从单页面到多页面的方法
2017/09/20 Javascript
在vue项目中引用Iview的方法
2018/09/14 Javascript
JS使用JSON.parse(),JSON.stringify()实现对对象的深拷贝功能分析
2019/03/06 Javascript
如何获取vue单文件自身源码路径
2019/05/06 Javascript
小程序实现上下移动切换位置
2019/09/23 Javascript
vuex actions异步修改状态的实例详解
2019/11/06 Javascript
解决 window.onload 被覆盖的问题方法
2020/01/14 Javascript
js实现无缝轮播图
2020/03/09 Javascript
JavaScript动画实例之粒子文本的实现方法详解
2020/07/28 Javascript
Python常见数字运算操作实例小结
2019/03/22 Python
提升Python程序性能的7个习惯
2019/04/14 Python
Windows下Sqlmap环境安装教程详解
2020/08/04 Python
Python 保存加载mat格式文件的示例代码
2020/08/04 Python
python定时截屏实现
2020/11/02 Python
Python控制鼠标键盘代码实例
2020/12/08 Python
Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
2012/05/30 面试题
大学生优秀的自我评价分享
2013/10/22 职场文书
捐款倡议书
2014/04/14 职场文书
网站创业计划书
2014/04/30 职场文书
欢迎标语大全
2014/06/21 职场文书
2014预备党员批评与自我批评思想汇报
2014/09/20 职场文书
告诉你一个秘密:富人致富的五大优点
2019/07/11 职场文书
MySQL的意向共享锁、意向排它锁和死锁
2022/07/15 MySQL