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 计算图片加载数量的代码
Jan 01 Javascript
基于jquery的blockui插件显示弹出层
Apr 14 Javascript
httpclient模拟登陆具体实现(使用js设置cookie)
Dec 11 Javascript
javascript实现简单的省市区三级联动
May 14 Javascript
如何利用AngularJS打造一款简单Web应用
Dec 05 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
May 30 Javascript
jQuery zTree树插件动态加载实例代码
May 11 jQuery
vue通过watch对input做字数限定的方法
Jul 13 Javascript
使用vuex的state状态对象的5种方式
Apr 19 Javascript
解决vue 中 echart 在子组件中只显示一次的问题
Aug 07 Javascript
element-ui upload组件多文件上传的示例代码
Oct 17 Javascript
Vue一次性简洁明了引入所有公共组件的方法
Nov 28 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 连接mysql连接被重置的解决方法
2011/02/15 PHP
PHP 命令行工具 shell_exec, exec, passthru, system详细使用介绍
2011/09/11 PHP
PHP、Python和Javascript的装饰器模式对比
2015/02/03 PHP
Yii框架中jquery表单验证插件用法示例
2016/10/18 PHP
PHPstorm启用自动换行的方法详解(IDE)
2020/09/17 PHP
jquery如何获取元素的滚动条高度等实现代码
2015/10/19 Javascript
详解javascript new的运行机制
2016/01/26 Javascript
微信小程序 开发工具快捷键整理
2016/10/31 Javascript
JavaScript实现Fly Bird小游戏
2016/12/15 Javascript
微信小程序 常用工具类详解及实例
2017/02/15 Javascript
AngularJS监听路由变化的方法
2017/03/07 Javascript
Vue.js 60分钟快速入门教程
2017/03/28 Javascript
jQuery中 DOM节点操作方法大全
2017/10/12 jQuery
Vue.js项目实战之多语种网站的功能实现(租车)
2019/08/07 Javascript
javascript实现抢购倒计时程序
2019/08/26 Javascript
详解利用nodejs对本地json文件进行增删改查
2019/09/20 NodeJs
详解Vue.js 响应接口
2020/07/04 Javascript
Python实现KNN邻近算法
2021/01/28 Python
Python全局变量与局部变量区别及用法分析
2018/09/03 Python
python使用BeautifulSoup与正则表达式爬取时光网不同地区top100电影并对比
2019/04/15 Python
Python3+Appium安装使用教程
2019/07/05 Python
python报错: 'list' object has no attribute 'shape'的解决
2020/07/15 Python
美国女孩洋娃娃店:American Girl
2017/10/24 全球购物
SmartBuyGlasses比利时:购买品牌太阳镜和眼镜
2019/08/09 全球购物
List、Map、Set三个接口,存取元素时,各有什么特点?
2015/09/27 面试题
小学教师师德感言
2014/02/10 职场文书
党建示范点实施方案
2014/03/12 职场文书
4s店市场专员岗位职责
2014/04/09 职场文书
路政管理求职信
2014/06/18 职场文书
企业工会工作总结2015
2015/05/13 职场文书
2015年领导干部廉洁自律工作总结
2015/05/26 职场文书
2016年第32个教师节红领巾广播稿
2015/12/18 职场文书
Python基础之Socket通信原理
2021/04/22 Python
利用Pycharm连接服务器的全过程记录
2021/07/01 Python
分布式Redis Cluster集群搭建与Redis基本用法
2022/02/24 Redis
R9700摩机记
2022/04/05 无线电