Angular学习笔记07——表单

##模板式表单 需要引入FormsModule,引入该模块后,在该模块下的所有表单都默认被装饰为模板模式。若仍要使用HTML模式,则指定<form ngNoForm>

| ------------- |:-------------:| -----------------------|
| NgForm | FormGroup | 定义在表单<form>标签上,指向整个表单 |
| NgModel | FormControl | 定义在表单行上,指向单行表单数据 |
| NgModelGroup | FormGroup | 定义div包含一组关联的表单行,统一处理 |

代码示例:

//NgForm 定义整个表单   同时指定表单提交事件,angular的表单不会再触发默认的表单提交
<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm.value)">
	<div>用户名:<input ngModel name="username" type="text"></div>//通过ngModel和name属性来绑定表单的元素
	<div>手机号:<input ngModel name="mobile" type="number"></div>
	<div ngModelGroup="passwordsGroup">//通过ngModelGroup来绑定多个表单元素,被绑定的表单元素会作为group的属性
		<div>密码:<input ngModel name="password" type="password"></div>
		<div>确认密码:<input ngModel name="pconfirm" type="password"></div>
	</div>
	<button type="submit">注册</button>
</form>
复制代码

##响应式表单 -FormControl-定义到表单行输入数据
username: FormControl = new FormControl("xxx")
如代码所示,前面模板式表单中的ngModel定义的username实质就是定义了如上一行代码
-FormGroup-定义了整个表单或多个FormControl集合

formModel: FromGroup = new FormGroup({
	from: new FormControl(),
	to: new FormControl()
});
复制代码

-FormArray-定义了一个可变长的集合,与FormGroup不同的是,不能通过属性名来访问,而是通过下标来获取,从0开始。

email: FormArray = new FormArray([
	new FromControl("aaaaa");
	new FromControl("bbbbb");
]);
复制代码

代码示例:

<form [formGroup]="fromModel" (submit)="onSubmit()">
	<input formControlName="username">
	<div fromGroupName="dateRange">
		开始日期:<input type="date" formControlName="from">
		截止日期:<input type="date" formControlName="to">
	</div>
	<div>
		<ul fromArrayName="emails">
			<li *ngFor="let e of this.formModel.get('emails').controls; let i=index;">
				<input type="text" [formControlName]="i">
			</li>
		</ul>
		<button type="button" (click)="addEmail()" >增加Email</button>
	</div>
	<div>
		<button type="submit">保存</button>
	</div>
</form>
复制代码

fromModel: FromGroup = new FormGroup({
	username: new FromControl("aaa"),
	dateRange: new FormGroup({
		from: new FormControl(),
		to: new FormControl()
	}),
	emails: new FormArray([
		new FromControl("aaaaa");
		new FromControl("bbbbb");
	])
});

addEmail(){
	let emails = this.formModel.get("emails") as FormArray;
	eamils.push(new FromControl);
}
复制代码

###FormBuilder的使用 constructor(fb: FormBuilder){ this.formModel = fb.group({ username: ['',校验方法], mobile: [''], passwordsGroup: fb.group({ password: [''], pconfirm: [''] }) },{'校验方法'}); } 使用FormBuilder可以简洁构造表单模型的代码。

##表单校验 校验器
1、使用预定义的校验器

constructor(fb: FormBuilder){
	this.formModel = fb.group({
		username: ['',[Validators.required,Validators.minLength(6)]],//必填,最小长度是6
		mobile: [''],
		passwordsGroup: fb.group({
			password: [''],
			pconfirm: ['']
		})
	});
}
onSubmit(){
	let isValid: boolean = this.formModel.get("username").valid;//校验结果
	let errors: ant = this.formModel.get("username").errors;//校验错误信息
}
复制代码

2、自定义校验器 xxxxx(control: AbstractContol):{[key: string]: ant}{return null}

//formcontrol的校验
mobileValidator(control: FormControl): any{
	var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
	let valid = myreg.test(control.value);
	return valid ? null : {mobile : true};
	//校验失败的时候返回空,成功返回对象和值
}
//formgroup的校验
equalValidator(group: FormGroup): any{
	let password:FromControl = group.get("password") as FormControl;
	let pconfirm:FromControl = group.get("pconfirm") as FormControl;
	let valid: boolean = (password.value === pconfirm.value);
	
	return valid ? null : {equ: {info:"密码和确认密码不一致"}}
}
//使用校验器
constructor(fb: FormBuilder){
	this.formModel = fb.group({
		username: ['',[Validators.required,Validators.minLength(6)]],//必填,最小长度是6
		mobile: ['',this.mobileValidator],
		passwordsGroup: fb.group({
			password: [''],
			pconfirm: ['']
		},{validator: this.equalValidators})
	});
}
复制代码

通用的校验器可以放到一个单独的ts文件中,作为公用的校验方法。
声明全局方法的时候使用 export function xxx(){}
对整个表单的校验结果是this.formModel.valid,只有所有的校验都成功的时候才会返回true;
表单错误信息显示:

<div>用户名:<input formControlName="username" type="text"></div>
<div [hidden]="!formModel.hasError('required','username')">
用户名是必填项</div>
<div [hidden]="!formModel.hasError('minlength','username')">
用户名最小长度是6</div>
<div>手机号:<input formControlName="mobile" type="text"></div>
<div [hidden]="!formModel.hasError('mobile','mobile')">
请输入正确的手机号</div>
<div formGroupName="passwordsGroup">
	<div>密码:<input formControlName="password" type="password"></div>
	<div [hidden]="!formModel.hasError('minlength',['passwordsGroup','password'])">
	密码最小长度是6</div>//在对formgroup中的formcontrol校验的时候要注意
	<div>确认密码:<input formControlName="pconfirm" type="password"></div>
	<div [hidden]="!formModel.hasError('equ','passwordsGroup')">
	{{formModel.geterror('equ','passwordsGroup')?.info}}</div>
</div>
复制代码

异步校验器
username: ['',校验方法,异步校验方法]
在bulider里面添加第三个函数,可以为需要校验的项新增一个异步的校验器,而校验的结果可以通过xxx(表单的formGroup).status来确认。
status有三个值 invalid pending valid invalid状态表示未被校验通过
pending状态即表示当前异步校验器仍在校验过程中
valid状态表示校验通过

###状态字段 toucheduntouched
当前formcontrol是否被点击过,若表单未被用户使用访问的时候,即不显示错误信息

<div>用户名:<input formControlName="username" type="text"></div>
<div [hidden]="formModel.get('username').valid || formModel.get('username').untouched">
	<div [hidden]="!formModel.hasError('required','username')">
	用户名是必填项</div>
	<div [hidden]="!formModel.hasError('minlength','username')">
	用户名最小长度是6</div>
</div>
复制代码

pristinedirty
若字段的值未被用户修改过,则pristine为true,dirty为false。否则为反。

<div>手机号:<input formControlName="mobile" type="text"></div>
<div [hidden]="formModel.get('mobile'.valid || formModel.get('mobile').pristine)">
	<div [hidden]="!formModel.hasError('mobile','mobile')">
	请输入正确的手机号</div>
</div>
复制代码

pending
当一个字段处于异步校验的时候,pending值为true

<div>手机号:<input formControlName="mobile" type="text"></div>
<div [hidden]="formModel.get('mobile'.valid || formModel.get('mobile').pristine)">
	<div [hidden]="!formModel.hasError('mobile','mobile')">
	请输入正确的手机号</div>
</div>
<div [hidden]="!formModel.get('mobile').pending">
	正在校验手机合法性
</div>
复制代码

###状态样式自定义 可以对ng-valid ng-untouched ng-pending等验证状态进行修改
或者自己对属性进行绑定:
<input [class.hasError]="formModel.get('username').invalid && formModel.get('username').touched" type="text" formControlName="username">
当表单未验证通过且被用户触碰过,添加上一个hasError的自定义样式

##自定义指令 ng g directive xxxx新建一个指令文件

@Directive({
	selector:'[xxxxx]',//在模板文件中使用时候直接使用xxxxx在标签属性中
	providers:[{provide:NG_VALIDATORS,useValue:xxxxFucntion,multi: true}]//provide的token是固定的,useValue指向方法,multi表示一个token下是否可以挂多个值
})复制代码

转载于:https://juejin.im/post/5a2df0b96fb9a045023b943c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值