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接口实现代码 (Interfaces In JavaScript)
Jun 11 Javascript
验证javascript中Object和Function的关系的三段简单代码
Jun 27 Javascript
JavaScript获取XML数据附示例截图
Mar 05 Javascript
Bootstrap table两种分页示例
Dec 23 Javascript
bootstrap table 表格中增加下拉菜单末行出现滚动条的快速解决方法
Jan 05 Javascript
jQuery实现返回顶部按钮和scroll滚动功能[带动画效果]
Jul 05 jQuery
JS对象序列化成json数据和json数据转化为JS对象的代码
Aug 23 Javascript
关于echarts在节点显示动态数据及添加提示文本所遇到的问题
Apr 20 Javascript
小程序实现列表点赞功能
Nov 02 Javascript
Vue组件Draggable实现拖拽功能
Dec 01 Javascript
如何让node运行es6模块文件及其原理详解
Dec 11 Javascript
swiperjs实现导航与tab页的联动
Dec 13 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 获取远程文件大小的3种解决方法
2013/07/11 PHP
一个好用的PHP验证码类实例分享
2013/12/27 PHP
ecshop 2.72如何修改后台访问地址
2015/03/03 PHP
php结合ajax实现手机发红包的案例
2016/10/13 PHP
JavaScript 继承使用分析
2011/05/12 Javascript
qTip2 精致的基于jQuery提示信息插件
2012/02/17 Javascript
禁止你的左键复制实用技巧
2013/01/04 Javascript
Android中的jQuery:AQuery简介
2014/05/06 Javascript
Jquery实现瀑布流布局(备有详细注释)
2015/07/31 Javascript
JS文字球状放大效果代码分享
2015/08/19 Javascript
每天一篇javascript学习小结(Function对象)
2015/11/16 Javascript
JavaScript编写简单的计算器
2015/11/25 Javascript
JS与jQuery遍历Table所有单元格内容的方法
2015/12/07 Javascript
angularjs自定义ng-model标签的属性
2016/01/21 Javascript
Jquery Easyui搜索框组件SearchBox使用详解(19)
2016/12/17 Javascript
Angular实现图片裁剪工具ngImgCrop实践
2017/08/17 Javascript
node.js 用socket实现聊天的示例代码
2017/10/17 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
nodejs一个简单的文件服务器的创建方法
2019/09/13 NodeJs
原生js实现拖拽移动与缩放效果
2020/08/24 Javascript
浅谈Python中chr、unichr、ord字符函数之间的对比
2016/06/16 Python
Python判断两个list是否是父子集关系的实例
2018/05/04 Python
使用python批量读取word文档并整理关键信息到excel表格的实例
2018/11/07 Python
Django中自定义查询对象的具体使用
2019/10/13 Python
在pycharm中debug 实时查看数据操作(交互式)
2020/06/09 Python
Python爬取你好李焕英豆瓣短评生成词云的示例代码
2021/02/24 Python
HTML5验证以及日期显示的实现详解
2013/07/05 HTML / CSS
HTML5 HTMLCollection和NodeList的区别详解
2020/04/29 HTML / CSS
Android面试题附答案
2014/12/08 面试题
Can a struct inherit from another class? (结构体能继承类吗)
2014/07/22 面试题
财务主管的岗位职责
2013/12/30 职场文书
主题婚礼策划方案
2014/02/10 职场文书
副职竞争上岗演讲稿
2014/05/12 职场文书
交通运输局四风问题对照检查材料思想汇报
2014/10/09 职场文书
护理工作个人总结
2015/03/03 职场文书
python tkinter模块的简单使用
2021/04/07 Python