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对象 ...
随机推荐
- ORACLE_SID的查找
SID是System IDentifier的缩写,而ORACLE_SID就是Oracle System Identifier的缩写,在Oracle系统中,ORACLE_SID以环境变量的形式出现,在特 ...
- Ad Exchange
品友互动-基于大数据技术的人工智能决策平台 http://www.ipinyou.com.cn/about?flag=milestones
- Codeblocks自动代码格式化+快捷键
Codeblocks自动代码格式化+快捷键 - u010112268的博客 - CSDN博客 https://blog.csdn.net/u010112268/article/details/8110 ...
- IO流入门-第九章-BufferedReader_BufferedWriter复制
利用BufferedReader和BufferedWriter进行复制粘贴 import java.io.*; public class BufferedReader_BufferedWriterCo ...
- 一篇搞定vue请求和跨域
vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基本Promise的HTTP请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对v ...
- IDEA 录制宏+设置快捷键 实现写时编译
参考: IDEA 录制宏+设置快捷键 实现写时编译:https://blog.csdn.net/wangjie919/article/details/79487981 IDEA 设置运行时不编译项目: ...
- java生成jar包
Java编写的application程序是否可以终于形成一个类似于exe一样的可执行文件.难道就仅仅能用命令行执行? 通常有两种.一种是制作一个可运行的JAR文件包.然后就能够像.chm文档一样双击运 ...
- C++之(::)运算符详解
::运算符 (::)是运算符中等级最高的,作用有三种,都是左关联的,都是为了更明确自己调用的对象或者函数: 全局作用域 类作用域 命名空间作用域 1.全局作用域 #include<iostrea ...
- (4.7)sql server2008 中的merge
简介 Merge关键字是一个神奇的DML关键字.它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小精悍:”根 ...
- 关于myeclipse+tomcat+struct2的热部署问题
今天满心欢喜的打开电脑来写程序,却不曾想到它竟然给我搞事情,前几天刚学的struct2热部署竟然不好用了.每次改java文件都要重新部署好麻烦,最后花了了好长时间才解决,必须在这里总结一下: (1)s ...