ng2 学习笔记(二)表单及表单验证
在上一篇文章中提到了表单,只说了表单的数据绑定,这一篇文章主要讲一下表单验证,为什么把表单单独拿出来学习,主要是因为,表单是商业应用的支柱,我们用它来执行登录、求助、下单、预订机票、安排会议,以及不计其数的其它数据录入任务,使用频率非常高。所以这块的重要性就显而易见了。
正文开始,这篇文章还是适合初学者,如果是大神,请指正不足:
先来看一下最终的样子:

表单很简单,模拟新增客户,用到表单的不少控件,
首先,要使用angular 的表单的一些控件,在使用ngModel做双向数据绑定之前,得先导入FormsModule, 把它加入 Angular 模块的imports列表。
在加载之前写组件。app.module.ts主文件代码如下:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; //引入表单模块
import { AppComponent } from './app.component';
import { UserForm } from './form.component'; // 引入自定义的组件
@NgModule({
imports: [ BrowserModule ,FormsModule],
declarations: [ AppComponent,UserForm],
bootstrap: [ AppComponent ]
})
export class AppModule { }
下面我们主要看一下表单这个组件内部的一些细节:
import { Component } from '@angular/core';
@Component({
selector:'hero-form',
template:`
<h2>FORM 表单</h2>
<hr />
<div class="container">
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<h4>客户管理</h4>
<form #forms="ngForm">
<div class="alert alert-danger" [hidden]="forms.form.valid">表单填写不合法</div>
<div class="form-group">
<label [class.text-danger]="!name.valid && forms.form.controls.name.touched">姓名</label>
<input type="text" class="form-control" name="name" [(ngModel)]="model.name" #name="ngModel" required>
</div>
<div class="form-group">
<label [class.text-danger]="!sex.valid && forms.form.controls.sex.touched">性别</label>
<select class="form-control" [(ngModel)]="model.sex" required name="sex" #sex="ngModel">
<option *ngFor="let s of sexs" [ngValue]="s">{{s}}</option>
</select>
</div>
<div class="form-group">
<label>来源</label>
<div>
<label class="checkbox-inline" *ngFor="let f of froms">
<input type="radio" [value]="f" name="from" [(ngModel)]="model.from" #from="ngModel" required> {{f}}
</label>
</div>
</div>
<div class="form-group">
<label>意向产品</label>
<div>
<label class="checkbox-inline" *ngFor="let p of model.mayBuy">
<input type="checkbox" [(ngModel)]="p.chose" [value]="p.pid" name="mayBuy" required> {{p.pname}}
</label>
</div>
</div>
<button type="button" (click)="submit(forms.form)" [class.btn-danger]="!forms.form.valid" [disabled]="!forms.form.valid" class="btn btn-primary">提交</button>
</form>
</div>
</div>
</div>
`
}) //这里有个小坑,如果这里按习惯加一个分号“;”,那就挂了,不能编译
export class UserForm {
sexs = ['男', '女','保密'];
products = [
{
pid:'p_001',
pname:'产品A',
chose:false
},
{
pid:'p_001',
pname:'产品B',
chose:false
},
{
pid:'p_001',
pname:'产品C',
chose:false
},
{
pid:'p_001',
pname:'产品D',
chose:false
}
];
froms = ['新增客户','老客户介绍'];
model = {
name:'',
sex:'',
from:'',
mayBuy:this.products
};
submitted = false;
submit(a:any){
console.log(this.model,a)
}
}
普通表单结构以及数据的双向绑定,就不多说了,主要说一下表单验证这块,即红色代码的地方。
交代一下基础概念,在ng 的表单模块中,单个控件(如:input)都会被跟踪状态,并且会在该控件上增加相应的class:
1)、控件是否已经被访问过:
是:touched;class:ng-touched
否:untouched; class:ng-untouched
2)、控件的值是否被修改过:
是:dirty;class:ng-dirty
否:pristine;class:ng-pristine
3)、控件的值是否合法:
是:valid;class:ng-valid
否:invalid;class:ng-invalid
整体表单也存在以上的3中状态,表单的验证证是通过这些跟踪的不同状态完成的。那么怎么访问到这些状态呢?
你可能已经注意到在form标签上有这样一段代码:
<form #forms="ngForm">
是的,#forms这个就是模版引用变量,上一篇文章提到过,这里只是把#forms初始化为 "ngForm";
现在我们就可以通过forms这个对象访问到我们需要的状态了,如果你不知道forms里都有啥,怎么用,那你就写个方法,把它打印出来,(click)="submit(forms)" 就可以了。
还有一个要注意的点,就是针对类似
<input type="text" class="form-control" name="name" [(ngModel)]="model.name" #name="ngModel" required>
这样的,name属性是必须要添加的,如果要对单个控件进行验证,我们可以加上模版引用变量#name="ngModel"快速访问到这个控件。
如果你需要正则表达式验证,只需加入pattern属性即可;
<input type="text" class="form-control" pattern="[a-zA-Z ]*" [(ngModel)]="model.name" name="name" />
以上述代码为例主要有以下几个点:
1、整体表单的合法性验证:
代码:forms.form.STATE,例如:forms.form.valid;forms.form.invalid
2、单个表单控件验证:
以这段代码为例:
<div class="form-group">
<label [class.text-danger]="!name.valid && forms.form.controls.name.touched">姓名</label>
3 <input type="text" class="form-control" name="name" [(ngModel)]="model.name" #name="ngModel" required>
4 </div>
这里的label的显示样式的判断条件其实是两种判断方法,
1)、!name.valid这个是使用模板引用变量来判断的;
2)、forms.form.controls.name.touched是使用forms.form这个对象判断的。
注意:forms.form这个对象里有很多子对象,这里使用的是form下controls这个对象查找到name判断的,至于是否应该controls这个子对象,有待研究。
本文到此结束,只是表单的一些初级应用,如果想了解更多,请点击这里查看API文档。
欢迎大家对本文所涉及的内容进行探讨,对有误的地方进行指正。
感谢阅读。
ng2 学习笔记(二)表单及表单验证的更多相关文章
- 操作系统学习笔记(二) 页式映射及windbg验证方式
页式映射 本系列截图来自网络搜索及以下基本书籍: <Windows内核设计思想> <Windows内核情景分析> <WINDOWS内核原理与实现> 一个32位虚拟地 ...
- Django学习笔记二
Django学习笔记二 模型类,字段,选项,查询,关联,聚合函数,管理器, 一 字段属性和选项 1.1 模型类属性命名限制 1)不能是python的保留关键字. 2)不允许使用连续的下划线,这是由dj ...
- amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules
amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...
- amazeui学习笔记二(进阶开发4)--JavaScript规范Rules
amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...
- 转)delphi chrome cef3 控件学习笔记 (二)
(转)delphi chrome cef3 控件学习笔记 (二) https://blog.csdn.net/risesoft2012/article/details/51260832 原创 2016 ...
- openresty 学习笔记二:获取请求数据
openresty 学习笔记二:获取请求数据 openresty 获取POST或者GET的请求参数.这个是要用openresty 做接口必须要做的事情.这里分几种类型:GET,POST(urlenco ...
- 微信小程序学习笔记二 数据绑定 + 事件绑定
微信小程序学习笔记二 1. 小程序特点概述 没有DOM 组件化开发: 具备特定功能效果的代码集合 体积小, 单个压缩包体积不能大于2M, 否则无法上线 小程序的四个重要的文件 *js *.wxml - ...
- [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计
源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...
- 《SQL必知必会》学习笔记二)
<SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...
- JDBC学习笔记二
JDBC学习笔记二 4.execute()方法执行SQL语句 execute几乎可以执行任何SQL语句,当execute执行过SQL语句之后会返回一个布尔类型的值,代表是否返回了ResultSet对象 ...
随机推荐
- 微信公众号 openId 支付 php中file_get_contents与curl性能比较分析
w http://www.jb51.net/article/57238.htm
- Spring MVC 框架结构介绍(二)
Spring MVC框架结构 Spring MVC是围绕DispatcherServlet设计的,DispatcherServlet向处理程序分发各种请求.处理程序默认基于@Controller和@R ...
- WebStorm7.0的破解版
EMBRACE 24718-1204201000001h6wzKLpfo3gmjJ8xoTPw5mQvYYA8vwka9tH!vibaUKS4FIDIkUfy!!f3C"rQCIRbShpS ...
- json/pickle/shelve/xml/configparser/hashlib/subprocess - 总结
序列化:序列化指把内存里的数据类型转成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes为什么要序列化:可以直接把内存数据(eg:10个列表,3个嵌套字典)存到硬盘 ...
- delphi inifile 支持 utf8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- 转!!java中File的delete()方法删除文件失败的原因
一般来说 java file.delete失败 有以下几个原因 1.看看是否被别的进程引用,手工删除试试(删除不了就是被别的进程占用)2.file是文件夹 并且不为空,有别的文件夹或文件, 3.极有可 ...
- 解决ubuntu 无法挂载移动硬盘问题 unknown filesystem type 'exfat'
Ubuntu 13.10 或以上 安装exfat-fuse: sudo apt-get install exfat-fuse Ubuntu 13.04 或以下 sudo apt-add-reposit ...
- Python模块学习之bs4
1.安装bs4 我用的ubuntu14.4,直接用apt-get命令就行 sudo apt-get install Python-bs4 2.安装解析器 Beautiful Soup支持Python标 ...
- 基于docker 搭建Elasticsearch5.6.4 分布式集群
说明: 准备2台机器,我这里有192. 和 192.168.0.164 192.168.0.164 作为master 192.168.0.107 作为普通node 一.环境 .docker 环境 .E ...
- Window mysql 安装配置
1.下载 安装包 mysql-noinstall--winx64.zip 2.解压缩zip包 安装路径 C:\Program Files\MySQL\mysql--winx64 3.配置环境变量 添加 ...