angularjs2 学习笔记(六) Form

Angular 2 Form表单

在angular2 form表单中我们需要了解表单数据绑定、数据验证、数据提交等内容,在下面的示例中并没有实际提交到后台,这部分内容在今后webapi中加以练习。

表单建立

<form (ngSubmit)="onSubmit(planetForm.value)" #planetform="ngForm">

</form>

这里是一个空的表单ngSubmit是一个事件,用于提交数据,数据则是整个form表单的内容,通常情况下我们的表单会绑定到我们的一个model中,那么提交的数据最后也是以json格式返回到后台来处理。

在表单中我们可以使用标准的html5控件来处理用户输入。

数据绑定

<div class="form-group">

<label class="col-xs-4 control-label" for="id">id : </label>

<div class="col-xs-8">

<input type="text" style="width: 300px" class="form-control" required

[(ngModel)]="myPlanet.id"

ngControl="id"

#planetid="ngForm">

<div [hidden]="planetid.valid || planetid.pristine" class="alert alert-danger">

The Name of green car is required !

</div>

</div>

</div>

这个一个表单输入的内容其中使用的是bootstrap的表单样式,在input中我们使用[(ngModel)](注意大小写)实现双向绑定,ngControl用于检测数据变化对应的是model中的字段,设置input的变量为ngForm来告诉angular 这个输入是这个表单内容。在vs中由于默认设置在粘贴html文本时会自动将大写字母变化成小写字母,所以angular的某些标签很容易发生错误,所以需要关闭这个自动转换,方法就是在vs的选项中将文本编辑器中的html高级选项下的粘贴时设置格式设置为false。

数据验证

html5内置的数据验证包括Required、minLength、maxLength、pattern ,我们可以将这些标签应用到我们的输入控件上,如

<input type="text" style="width: 300px" class="form-control" required maxlength="10" minLength="4"

[(ngModel)]="myPlanet.id"

ngControl="name"

#planetid="ngForm">

<div [hidden]="planetid.valid || planetid.pristine" class="alert alert-danger">

The id is required !

</div>

这里的"planetid.valid || planetid.pristine是验证这个input输入是否有效,或者数据是否改变。

Formbuilder

Formbuilder是我们可以采用的另一种方式来创建Form,这种方式是以模型驱动完成的,更适合我们进行编码控制,有利于我们将逻辑与视图分离。

Angular2 form 作用机制由两个主要的组件Controls和Controls group。

Control:包含值和验证状态,一个control能够被邦定可以包含三个可选参数(缺省值,验证,异步验证),例如

this.username = new Control(‘Default value‘, Validators.required, usernameValidator.checkIfAvailable);

在html应用时使用ngControl标签绑定这个控件

<input required type=”text” ngControl=”username” />

这里定义的username与input中ngControl指定的名称要一致。

Control Groups:form定义的一部分,通过将多个cotrol组合在一起形成组。

class App {
 
 name: Control;
 username: Control;
 email: Control;
 
 form: ControlGroup;
 
 constructor(private builder:
FormBuilder) {
 
   this.name = new Control(‘‘,
Validators.required);
   this.email = new Control(‘‘,
Validators.required);
   this.username = new Control(‘‘,
Validators.required);
 
   this.form = builder.group({
     name: this.name,
     email: this.email,
     username: this.username
   });
 }

};

html应用时加入ngFormModel来标识。

<form [ngFormModel]=”form”>

自定义验证

除了内置验证外,我们还可以自定义验证,例子如下

import {Control} from ‘angular2/common‘;

interface ValidationResult

{

[key: string]: boolean;

}

export class UsernameValidator

{

static startsWithNumber( control: Control ): ValidationResult

{

if ( control.value !="" && !isNaN( control.value.charAt( 0 ) ) ){

return { "startsWithNumber": true };

}

return null;

}

}

这个自定义验证如果输入的值中首字母是数字则验证无效,返回null则验证通过。使用方法

首先import {UsernameValidator} from ‘./customValidate‘;

然后在我们需要验证的控件上加入自定义验证

this.name = new Control( this.myPlanet.name, UsernameValidator.startsWithNumber );

错误提示

<div *ngIf="name.dirty && !name.valid">

<p *ngIf="name.errors.startsWithNumber">

Your name can‘t start with a number

</p>

</div>

这里的errors. startsWithNumber就是我们自定义返回的key值。最好的方式是使用hasError,因为如果返回的startsWithNumber是null的话会引发异常

<p *ngIf="name.hasError(‘startsWithNumber‘)">

异步验证

如果我们需要使用service去到后台获取数据并验证,则我们需要使用异步验证方式,这里的例子使用promise模拟。

static usernameTaken( control: Control ): Promise<ValidationResult>

{

let q = new Promise(( resolve, reject ) =>

{

setTimeout(() =>

{

if ( control.value !== ‘oldkingsir‘) {

resolve( { "usernameTaken": true});

} else {

resolve( null );

}

}, 1000 )

});

return q;

}

真实应用可能是

class ProductValidator {

static productExists(control: Control): {[key: string]: any} {

return new Promise( resolve => {

var productService = new ProductService();

var product: Product;

productService.getProduct(control.value)

.then(productFound => {

if (productFound == null) {

// need to return something if not ok

resolve({productExists: false});

} else {

// need to return null if ok

resolve(null);

}

});

});

}

}

下面需要使用验证的第三个参数,方式如下

this.name = new Control( this.myPlanet.name,UsernameValidator.startsWithNumber, UsernameValidator.usernameTaken );

html

<div *ngIf="name.dirty && !name.valid">

<span *ngIf="name.pending">Checking istaken...</span>

<p *ngIf="name.hasError(‘startsWithNumber‘)">

Your name can‘t start with a number

</p>

<p *ngIf="name.hasError(‘usernameTaken‘)">

Your name is already taken

</p>

</div>

这里使用了pending来友好提示验证中。

组合验证

如果需要进行多个验证可以使用compose组合验证,如下

this.name = new Control(‘‘, Validators.compose([Validators.required, Validators.minLength(4)]));

最后如果整个表单验证不通过我们不提交则可以在提交按钮上加以处理,如

<button type="submit" class="btn btn-default" [disabled]="!form.valid">Submit</button>

时间: 2024-12-29 11:19:18

angularjs2 学习笔记(六) Form的相关文章

Angularjs2 学习笔记

angularjs2 学习笔记(一) 开发环境搭建 开发环境,vs2013 update 5,win7 x64,目前最新angular2版本为beta 17 第一步:安装node.js 安装node.js(https://nodejs.org/en/),为的是能够使用npm获得angular2.0的开发包 验证是否安装成功 cmd下输入 node -v npm -v 第二步:在vs2013上安装typescript 安装完成后在项目中可以添加typescript项目了,并且在项目属性栏中会有ty

python之raw_input()(学习笔记六)

python之raw_input()(学习笔记六) 我们经常使用raw_input()读取用户的输入,如下例子所示: >>> name = raw_input('please input your name:'),截图如下: 下面简单说下,raw_input()与if搭配使用,脚本如下: #!/usr/bin/env python # -*- coding:utf-8 -*- birth = raw_input('birth:') if birth < 2000: print '0

swift学习笔记(六)析构过程和使用闭包对属性进行默认值赋值

一.通过闭包和函数实现属性的默认值 当某个存储属性的默认值需要定制时,可以通过闭包或全局函数来为其提供定制的默认值. 注:全局函数结构体和枚举使用关键字static标注    函数则使用class关键字标注 当对一个属性使用闭包函数进行赋值时,每当此属性所述的类型被创建实例时,对应的闭包或函数会被调用,而他们的返回值会被作为属性的默认值. ESC: Class SomeCLass{ let someProperty:SomeType={ //给someProperty赋一个默认值 //返回一个与

java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessController的checkPerssiom方法,访问控制器AccessController的栈检查机制又遍历整个 PerssiomCollection来判断具体拥有什么权限一旦发现栈中一个权限不允许的时候抛出异常否则简单的返回,这个过程实际上比我的描述要复杂 得多,这里我只是简单的一句带过,因为这

初探swift语言的学习笔记六(ARC-自动引用计数,内存管理)

Swift使用自动引用计数(ARC)来管理应用程序的内存使用.这表示内存管理已经是Swift的一部分,在大多数情况下,你并不需要考虑内存的管理.当实例并不再被需要时,ARC会自动释放这些实例所使用的内存. 另外需要注意的: 引用计数仅仅作用于类实例上.结构和枚举是值类型,而非引用类型,所以不能被引用存储和传递. swift的ARC工作过程 每当创建一个类的实例,ARC分配一个内存块来存储这个实例的信息,包含了类型信息和实例的属性值信息. 另外当实例不再被使用时,ARC会释放实例所占用的内存,这些

Linux System Programming 学习笔记(六) 进程调度

1. 进程调度 the process scheduler is the component of a kernel that selects which process to run next. 进程调度器需要使 处理器使用率最大化,并且提供 使多个进程并发执行的虚拟 Deciding which processes run, when, and for how long is the process scheduler's fundamental responsibility. 时间片:th

Lua学习笔记(六):函数-续

Lua中的函数是带有词法定界(lexical scoping)的第一类值(first-class values).第一类值指:在Lua中函数和其他值(数值.字符串)一样,函数可以被存放在变量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值.词法定界指:嵌套的函数可以访问他外部函数中的变量.这一特性给Lua提供了强大的编程能力. Lua中关于函数稍微难以理解的是函数也可以没有名字,匿名的.当我们提到函数名(比如print),实际上是说一个指向函数的变量,像持有其他类型的变量一样:

laravel3学习笔记(六)

原作者博客:ieqi.net ==================================================================================================== ORM Laravel3中MVC体系中Model里最重要的组成部分无疑是ORM了,ORM — object-relational mapper — 将数据操作面向对象化,使得整个web框架的核心风格统一,降低整体复杂度,为开发者提供便利. Laravel3中的ORM叫

IBatis.Net学习笔记六--再谈查询

在IBatis.Net学习笔记五--常用的查询方式 中我提到了一些IBatis.Net中的查询,特别是配置文件的写法. 后来通过大家的讨论,特别是Anders Cui 的提醒,又发现了其他的多表查询的方式.在上一篇文章中我提到了三种方式,都是各有利弊:第一种方式当数据关联很多的情况下,实体类会很复杂:第二种方式比较灵活,但是不太符合OO的思想(不过,可以适当使用):第三种方式最主要的问题就是性能不太理想,配置比较麻烦. 下面是第四种多表查询的方式,相对第二种多了一点配置,但是其他方面都很好(当然

[傅里叶变换及其应用学习笔记] 六. 热方程讨论

这份是本人的学习笔记,课程为网易公开课上的斯坦福大学公开课:傅里叶变换及其应用. 上节课讲到,在对非周期函数进行傅里叶分析时,有 $C_k = \displaystyle{\frac{1}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}}f(t)e^{-2\pi i\frac{k}{T}t}dt }$ $f(t) = \displaystyle{\sum_{k=-\infty}^{\infty}C_ke^{2\pi i\frac{k}{T}t} }$ 我们希望仅让$T\to