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函数
May 27 Javascript
根据出生日期自动取得星座的js代码
Jul 20 Javascript
解决Jquery鼠标经过不停滑动的问题
Mar 03 Javascript
jQuery 插件开发指南
Nov 14 Javascript
基于JS实现类似支付宝支付密码输入框
Sep 02 Javascript
浅谈jquery.form.js的ajaxSubmit和ajaxForm的使用
Sep 09 Javascript
微信小程序 省市区选择器实例详解(附源码下载)
Jan 05 Javascript
canvas 实现中国象棋
Feb 17 Javascript
Vue.use源码学习小结
Jun 20 Javascript
详解js模板引擎art template数组渲染的方法
Oct 09 Javascript
vue服务端渲染操作简单入门实例分析
Aug 28 Javascript
微信小程序自定义导航栏(模板化)
Nov 15 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 adodb连接不同数据库
2009/03/19 PHP
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
2011/10/29 PHP
PHP中set_include_path()函数相关用法分析
2016/07/18 PHP
驱动事件的addEvent.js代码
2007/03/27 Javascript
JQuery 学习笔记 选择器之六
2009/07/23 Javascript
仿新浪微博返回顶部的jquery实现代码
2012/10/01 Javascript
常用的几段javascript代码分享
2014/03/25 Javascript
ionic cordova一次上传多张图片(类似input file提交表单)的实现方法
2016/12/16 Javascript
Angular中$broadcast和$emit的使用方法详解
2017/05/22 Javascript
微信小程序实现图片放大预览功能
2020/10/22 Javascript
React-native桥接Android原生开发详解
2018/01/17 Javascript
p5.js入门教程之小球动画示例代码
2018/03/15 Javascript
LayUI数据接口返回实体封装的例子
2019/09/12 Javascript
vue接口请求加密实例
2020/08/11 Javascript
vue中使用vue-pdf的方法详解
2020/09/05 Javascript
[43:41]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
python将ip地址转换成整数的方法
2015/03/17 Python
Python3指定路径寻找符合匹配模式文件
2015/05/22 Python
Windows中安装使用Virtualenv来创建独立Python环境
2016/05/31 Python
python 处理数字,把大于上限的数字置零实现方法
2019/01/28 Python
python基于K-means聚类算法的图像分割
2019/10/30 Python
python使用ctypes库调用DLL动态链接库
2020/10/22 Python
Selenium 安装和简单使用的实现
2020/12/04 Python
灵活运用CSS3特性绘制简易版围棋效果
2016/09/28 HTML / CSS
澳大利亚最大的百货公司:Myer
2018/12/21 全球购物
屈臣氏菲律宾官网:Watsons菲律宾
2020/06/30 全球购物
常用UNIX 命令(Linux的常用命令)
2013/07/10 面试题
课例研修方案
2014/05/31 职场文书
环卫工人先进事迹材料
2014/06/02 职场文书
航空学院求职信
2014/06/11 职场文书
会计专业应届生自荐信
2014/06/28 职场文书
反对四风自我剖析材料
2014/10/07 职场文书
结婚保证书(卖身契)
2015/02/26 职场文书
Python+Appium自动化测试的实战
2021/06/30 Python
python+pytest接口自动化之token关联登录的实现
2022/04/06 Python
详解Flutter和Dart取消Future的三种方法
2022/04/07 Java/Android