在上一篇文章中提到了表单,只说了表单的数据绑定,这一篇文章主要讲一下表单验证,为什么把表单单独拿出来学习,主要是因为,表单是商业应用的支柱,我们用它来执行登录、求助、下单、预订机票、安排会议,以及不计其数的其它数据录入任务,使用频率非常高。所以这块的重要性就显而易见了。

正文开始,这篇文章还是适合初学者,如果是大神,请指正不足:

先来看一下最终的样子:

表单很简单,模拟新增客户,用到表单的不少控件,

首先,要使用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 学习笔记(二)表单及表单验证的更多相关文章

  1. 操作系统学习笔记(二) 页式映射及windbg验证方式

    页式映射 本系列截图来自网络搜索及以下基本书籍: <Windows内核设计思想> <Windows内核情景分析> <WINDOWS内核原理与实现> 一个32位虚拟地 ...

  2. Django学习笔记二

    Django学习笔记二 模型类,字段,选项,查询,关联,聚合函数,管理器, 一 字段属性和选项 1.1 模型类属性命名限制 1)不能是python的保留关键字. 2)不允许使用连续的下划线,这是由dj ...

  3. amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules

    amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...

  4. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  5. 转)delphi chrome cef3 控件学习笔记 (二)

    (转)delphi chrome cef3 控件学习笔记 (二) https://blog.csdn.net/risesoft2012/article/details/51260832 原创 2016 ...

  6. openresty 学习笔记二:获取请求数据

    openresty 学习笔记二:获取请求数据 openresty 获取POST或者GET的请求参数.这个是要用openresty 做接口必须要做的事情.这里分几种类型:GET,POST(urlenco ...

  7. 微信小程序学习笔记二 数据绑定 + 事件绑定

    微信小程序学习笔记二 1. 小程序特点概述 没有DOM 组件化开发: 具备特定功能效果的代码集合 体积小, 单个压缩包体积不能大于2M, 否则无法上线 小程序的四个重要的文件 *js *.wxml - ...

  8. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  9. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  10. JDBC学习笔记二

    JDBC学习笔记二 4.execute()方法执行SQL语句 execute几乎可以执行任何SQL语句,当execute执行过SQL语句之后会返回一个布尔类型的值,代表是否返回了ResultSet对象 ...

随机推荐

  1. 巨蟒python全栈开发-第22天 内置常用模块1

    一.今日主要内容 1.简单了解模块 你写的每一个py文件都是一个模块 数据结构(队列,栈(重点)) 还有一些我们一直在使用的模块 buildins 内置模块.print,input random 主要 ...

  2. hdu 1159 Common Subsequence 【LCS 基础入门】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1159 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  3. navicat 中执行sql脚本 喊中文错误

    执行内容和上篇一样,只是换了工具. 执行成功,但是数据库对应中文没有内容. sql脚本的编码是asci 执行的时候选择gbk 编码

  4. django 配置 多数据库

    django多数据库 阅读spider platform时发现前端项目中使用了多数据库,那么django实现多数据库需要哪些配置呢,又如何使用呢? 定义及路由机制 定义 在settings里面的DAT ...

  5. 报错:Cannot remove entries from nonexistent file c:\program files\anaconda3\lib\site-packages\easy-install.pth

    Outline 这两天通过“掘金量化终端”跑模型策略,之前装好环境一直ok,可以顺畅的Running~ 下午重装了下 Anaconda,刚才跑的时候提示 缺少“gm”模块 (掘金量化必须包): 就按照 ...

  6. Ubuntu 16.04安装JDK并配置环境变量(转发:https://blog.csdn.net/yan3013216087/article/details/78307258)

    系统版本:Ubuntu 16.04 JDK版本:jdk1.8.0_121 1.官网下载JDK文件jdk-8u121-linux-x64.tar.gz 我这里下的是最新版,其他版本也可以 2.创建一个目 ...

  7. 学点TCPDUMP

    [root@future ~]# yum install tcpdump 官网地址: https://nmap.org/ 还有中文手册,太感动了 https://nmap.org/man/zh/man ...

  8. php 获取数组中的key值

    <?php $arr = array( 'book' => 1, 'data' => 'data', 'music' => 'music', 'img' => 'img' ...

  9. 微信小程序组件button

    表单组件button:官方文档 Demo Code: var types=['default', 'primary', 'warn']; var pageObject = { data: { defa ...

  10. nodejs入门-做一个代理服务器

    看到node.js的httpServer和http.request,第一个想法居然是可以用它做一个代理服务器下面代码,实现了代理的基本功能,通过网络的代理设置将你的浏览器的请求转到这个httpServ ...