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 相关文章推荐
Jquery知识点二 jquery下对数组的操作
Jan 15 Javascript
如何判断元素是否为HTMLElement元素
Dec 06 Javascript
jquery无刷新验证邮箱地址实现实例
Feb 19 Javascript
JavaScript弹出新窗口后向父窗口输出内容的方法
Apr 06 Javascript
解决JS无法调用Controller问题的方法
Dec 31 Javascript
jQuery Easyui 验证两次密码输入是否相等
May 13 Javascript
利用css+原生js制作简单的钟表
Apr 07 Javascript
React.js中常用的ES6写法总结(推荐)
May 09 Javascript
JS中的事件委托实例浅析
Mar 22 Javascript
浅谈针对Vue相同路由不同参数的刷新问题
Sep 29 Javascript
vue单页应用的内存泄露定位和修复问题小结
Aug 02 Javascript
React+EggJs实现断点续传的示例代码
Jul 07 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排序算法(冒泡排序,快速排序)
2012/10/09 PHP
使用php伪造referer的方法 利用referer防止图片盗链
2014/01/20 PHP
PHP微信分享开发详解
2017/01/14 PHP
Paypal实现循环扣款(订阅)功能
2017/03/23 PHP
在php的yii2框架中整合hbase库的方法
2018/09/20 PHP
PHP7 新增常量
2021/03/09 PHP
Javascript 获取链接(url)参数的方法[正则与截取字符串]
2010/02/09 Javascript
JavaScript高级程序设计 阅读笔记(十二) js内置对象Math
2012/08/14 Javascript
JavaScript 中的日期和时间及表示标准介绍
2013/08/21 Javascript
jquery Tab效果和动态加载的简单实例
2013/12/11 Javascript
Visual Studio中js调试的方法图解
2014/06/30 Javascript
一个JavaScript获取元素当前高度的实例
2014/10/29 Javascript
node.js中的fs.fsync方法使用说明
2014/12/15 Javascript
jQuery多级弹出菜单插件ZoneMenu
2014/12/18 Javascript
基于JavaScript实现表单密码的隐藏和显示出来
2016/03/02 Javascript
vue分页组件table-pagebar使用实例解析
2020/11/15 Javascript
JS中的作用域链
2017/03/01 Javascript
微信小程序页面传值实例分析
2017/04/19 Javascript
layui前段框架日期控件使用方法详解
2017/05/19 Javascript
关于Mac下安装nodejs、npm和cnpm的教程
2018/04/11 NodeJs
python编写微信远程控制电脑的程序
2018/01/05 Python
python 拷贝特定后缀名文件,并保留原始目录结构的实例
2018/04/27 Python
python之pyqt5通过按钮改变Label的背景颜色方法
2019/06/13 Python
Python使用socketServer包搭建简易服务器过程详解
2020/06/12 Python
简单了解Django项目应用创建过程
2020/07/06 Python
最新PyCharm从安装到PyCharm永久激活再到PyCharm官方中文汉化详细教程
2020/11/17 Python
Bluebella法国官网:英国性感内衣品牌
2019/05/03 全球购物
预备党员政审材料
2014/02/04 职场文书
能源工程专业应届生求职信
2014/03/01 职场文书
质量承诺书范文
2014/03/27 职场文书
小露珠教学反思
2014/04/30 职场文书
青年志愿者先进事迹
2014/05/06 职场文书
大学生求职信
2014/06/17 职场文书
出纳试用期自我鉴定范文
2014/09/16 职场文书
停发工资证明范本
2015/06/12 职场文书
Vue项目打包、合并及压缩优化网页响应速度
2021/07/07 Vue.js