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 相关文章推荐
JS简单的轮播的图片滚动实例
Jun 17 Javascript
JQuery选择器绑定事件及修改内容的方法
Jan 23 Javascript
浅析Bootstrap组件之面板组件
May 04 Javascript
Javascript获取随机数的实现方法
Jun 22 Javascript
jQuery实现遮罩层登录对话框
Dec 29 Javascript
5种JavaScript脚本加载的方式
Jan 16 Javascript
Vue.js使用$.ajax和vue-resource实现OAuth的注册、登录、注销和API调用
May 10 Javascript
express如何使用session与cookie的方法
Jan 30 Javascript
JavaScript基于数组实现的栈与队列操作示例
Dec 22 Javascript
vue watch关于对象内的属性监听
Apr 22 Javascript
js中arguments对象的深入理解
May 14 Javascript
vue项目中自定义video视频控制条的实现代码
Apr 26 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
MYSQL数据库初学者使用指南
2006/11/16 PHP
彻底杜绝PHP的session cookie错误
2009/08/09 PHP
php calender(日历)二个版本代码示例(解决2038问题)
2013/12/24 PHP
php使用cookie保存登录用户名的方法
2015/01/26 PHP
php微信公众号js-sdk开发应用
2016/11/28 PHP
PHP自动识别当前使用移动终端
2018/05/21 PHP
php微信分享到朋友圈、QQ、朋友、微博
2019/02/18 PHP
Js基础学习资料
2010/11/23 Javascript
angularjs自定义ng-model标签的属性
2016/01/21 Javascript
JS函数的定义与调用方法推荐
2016/05/12 Javascript
js判断数组key是否存在(不用循环)的简单实例
2016/08/03 Javascript
Web性能优化系列 10个提升JavaScript性能的技巧
2016/09/27 Javascript
详解js产生对象的3种基本方式(工厂模式,构造函数模式,原型模式)
2017/01/09 Javascript
DOM事件探秘篇
2017/02/15 Javascript
带你了解session和cookie作用原理区别和用法
2017/08/14 Javascript
node+express+ejs使用模版引擎做的一个示例demo
2017/09/18 Javascript
详解Webpack实战之构建 Electron 应用
2017/12/25 Javascript
Angular浏览器插件Batarang介绍及使用
2018/02/07 Javascript
JavaScript实现浅拷贝与深拷贝的方法分析
2018/07/05 Javascript
mpvue 如何使用腾讯视频插件的方法
2018/07/16 Javascript
Vue数据绑定简析小结
2019/05/07 Javascript
vue将后台数据时间戳转换成日期格式
2019/07/31 Javascript
jQuery实现动态加载瀑布流
2020/09/01 jQuery
js实现右键弹出自定义菜单
2020/09/08 Javascript
python实现的解析crontab配置文件代码
2014/06/30 Python
利用Python查看目录中的文件示例详解
2017/08/28 Python
对numpy中布尔型数组的处理方法详解
2018/04/17 Python
python 用for循环实现1~n求和的实例
2019/02/01 Python
python多进程并行代码实例
2019/09/30 Python
浅析Python 条件控制语句
2020/07/15 Python
python利用 keyboard 库记录键盘事件
2020/10/16 Python
Eton丹麦官网:精美的男式衬衫
2020/05/27 全球购物
自主招生自荐信格式
2013/12/03 职场文书
生产部统计员岗位职责
2014/01/05 职场文书
药店采购员岗位职责
2014/09/30 职场文书
python 如何用map()函数创建多线程任务
2021/04/07 Python