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系列(10) JavaScript核心(晋级高手必读篇)
Jan 15 Javascript
javascript表单验证 - Parsley.js使用和配置
Jan 25 Javascript
Javascript 拖拽的一些简单的应用(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
JS+CSS实现鼠标滑过时动态翻滚的导航条效果
Sep 24 Javascript
JS实现可自定义大小,可双击关闭的弹出层效果
Oct 16 Javascript
微信小程序 radio单选框组件详解及实例代码
Jan 10 Javascript
详解vue axios中文文档
Sep 12 Javascript
微信小程序实现图片上传、删除和预览功能的方法
Dec 18 Javascript
vue-cli开发时,关于ajax跨域的解决方法(推荐)
Feb 03 Javascript
bootstrap中的导航条实例代码详解
May 20 Javascript
vue通过video.js解决m3u8视频播放格式的方法
Jul 30 Javascript
详解微信小程序中var、let、const用法与区别
Jan 11 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
海贼王动画变成“真人”后,凯多神还原,雷利太帅了!
2020/04/09 日漫
调用WordPress函数统计文章访问量及PHP原生计数器的实现
2016/03/21 PHP
Yii中CGridView禁止列排序的设置方法
2016/07/12 PHP
改版了网上的一个js操作userdata
2007/04/27 Javascript
JavaScript Archive Network 集合
2007/05/12 Javascript
Autocomplete Textbox Example javascript实现自动完成成功
2007/08/17 Javascript
javascript contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
2010/02/04 Javascript
jquery 的 $(&quot;#id&quot;).html() 无内容的解决方法
2010/06/07 Javascript
jQuery使用之标记元素属性用法实例
2015/01/19 Javascript
Nginx上传文件全部缓存解决方案
2015/08/17 Javascript
angular.bind使用心得
2015/10/26 Javascript
jQuery中设置form表单中action值的实现方法
2016/05/25 Javascript
Javascript中indexOf()和lastIndexOf应用方法实例
2016/08/24 Javascript
基于Marquee.js插件实现的跑马灯效果示例
2017/01/25 Javascript
利用Jquery实现几款漂亮实用的时间轴(附示例代码)
2017/02/15 Javascript
jQuery实现div跟随鼠标移动
2020/08/20 jQuery
vue.js路由跳转详解
2017/08/28 Javascript
es6基础学习之解构赋值
2018/12/10 Javascript
小程序server请求微信服务器超时的解决方法
2019/05/21 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
2020/09/09 Javascript
详解微信小程序动画Animation执行过程
2020/09/23 Javascript
如何使用JS console.log()技巧提高工作效率
2020/10/14 Javascript
[06:45]DOTA2卡尔工作室 英雄介绍幻影长矛手篇
2013/07/12 DOTA
Python  pip安装lxml出错的问题解决办法
2017/02/10 Python
Python简单计算数组元素平均值的方法示例
2017/12/26 Python
Python 多线程搜索txt文件的内容,并写入搜到的内容(Lock)方法
2019/08/23 Python
Casadei卡萨蒂官网:意大利奢侈鞋履品牌
2017/10/28 全球购物
Ancheer官方户外和运动商店:销售电动自行车
2019/08/07 全球购物
力学专业毕业生自荐信
2013/11/17 职场文书
房地产开盘策划方案
2014/02/10 职场文书
幼儿园大班评语大全
2014/04/17 职场文书
中学生纪念九一八事变演讲稿
2014/09/14 职场文书
2015年春节标语口号
2014/12/09 职场文书
2015年五四青年节演讲稿
2015/03/18 职场文书
外出考察学习心得体会
2016/01/18 职场文书
SQL实现LeetCode(177.第N高薪水)
2021/08/04 MySQL