1、表单控件

使用表单控件有三个步骤。

  1. 注册响应式表单模块。该模块声明要用在响应式表单中的指令。
  2. 生成一个新的​​FormControl​​ 实例,并把它保存在组件中。
  3. 在模板中注册这个​​FormControl​​。

注册响应式表单模块
要使用响应式表单控件,就要从 ​​​@angular/forms​​​ 包中导入 ​​ReactiveFormsModule​​​,并把它添加到你的 NgModule 的 ​​imports​​ 数组中。

import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
ReactiveFormsModule
],
})

要注册一个表单控件,就要导入 ​​FormControl​​​ 类并创建一个 ​​FormControl​​ 的新实例,将其保存为类的属性。

import { FormControl } from '@angular/forms';
export class STHomeComponent {
ageForm:FormControl = new FormControl(6);
}

<!-- 动态表单控件 -->
年龄:<input type="text" [formControl]="ageForm">
<br>
<p>年龄:{{ageForm.value}}</p>
<button (click)="ageChangeFun()">长大18岁</button>

修改ageForm值可以通过​​FormControl​​​ 提供的 ​​setValue()​​ 方法

ageChangeFun(){
this.ageForm.setValue(18)
}

2、表单控件分组

响应式表单提供了两种把多个相关控件分组到同一个输入表单中的方法
要将表单组添加到此组件中,请执行以下步骤。

  1. 创建一个​​FormGroup​​ 实例。
  2. 把这个​​FormGroup​​ 模型关联到视图。
  3. 保存表单数据。

创建一个 FormGroup 实例

在组件类中创建一个名叫 ​​loginForm​​​ 的属性,并设置为 ​​FormGroup​​​ 的一个新实例。要初始化这个 ​​FormGroup​​,请为构造函数提供一个由控件组成的对象,对象中的每个名字都要和表单控件的名字一一对应

import { FormGroup, FormControl } from '@angular/forms';
export class STHomeComponent {
loginForm = new FormGroup({
userName: new FormControl(''),
password: new FormControl(''),
});
}
//模板渲染
<!-- 动态表单控件组 -->
<form [formGroup]="loginForm">
<label>
账号: <input required type="text" formControlName="userName">
</label>
<br>
<label>
密码: <input type="password" formControlName="password">
</label>
<br>
<button (click)="subFormFun()">提交</button>
</form>

3、表单验证

表单元素添加​​required​​​关键字表示必填,通过绑定​​ngModel​​的引用可以拿到到当前组件的信息,通过引用获取到验证的信息

export class AppComponent {
fromData={
name:'',
password:''
};
subBtnFun(obj:any){
console.log(obj);
}
}

<!-- 表单验证 -->
<form action="">
账号:<input required #nameInp="ngModel" type="text" [(ngModel)]="fromData.name" name="userName">
<span *ngIf="!nameInp.valid">请输入账号</span>
<br>
密码:<input required #pasInp="ngModel" type="text" [(ngModel)]="fromData.password" name="password">
<span>验证结果:{{pasInp.valid }}</span>
<br>
<button (click)="subBtnFun(nameInp)">提交</button>
</form>

通过 ngModel 跟踪修改状态与有效性验证,它使用了三个 CSS 类来更新控件,以便反映当前状态。

状态

为 true 时的类

为 false 时的类

控件已经被访问过

​ng-touched​

​ng-untouched​

控件值已经变化

​ng-dirty​

​ng-pristine​

控件值是有效的

​ng-valid​

​ng-invalid​

4、自定义表单验证

先引入表单的内置依赖

import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';

//构造函数里注入FormBuilder
constructor(private fbCustom:) { }

valiDataForm:FormGroup = this.fbCustom.group({
userName: ['', [Validators.required,
Validators.maxLength(18),
Validators.minLength(6)]],
password: ['', [this.passWordVal]],
phone: ['', [Validators.required,this.phoneVal],]
});

passWordVal(password: FormControl):object{
let value = password.value || '';
if(!value){
return {msg:'请输入密码'}
}else{
const valid = value.match(/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/);
return valid?{}:{msg:'密码至少包含 数字和英文,长度6-20'}
}
}

phoneVal(phone: FormControl): object {
const value = phone.value || '';
if(!value) return {msg:'请输入手机号'}
const valid = value.match(/[0-9]{11}/);
return valid ? {} :{msg:'手机号必须是11位数字'}
}

subvaliDataFormFun(){
console.log(this.valiDataForm.get('userName'));
}

// 渲染结构
<!-- 自定义表单验证 -->
<form [formGroup]="valiDataForm">
<label>
账号: <input required type="text" formControlName="userName">
</label>
<p *ngIf="valiDataForm.get('userName')?.errors?.['required']">请输入账号</p>
<p *ngIf="valiDataForm.get('userName')?.errors?.['minlength']?.requiredLength
||valiDataForm.get('userName')?.errors?.['maxlength']?.requiredLength">账号长度在6-18位之间</p>
<br>
<label>
密码: <input type="password" formControlName="password">
</label>
<p *ngIf="valiDataForm.get('password')?.errors?.['msg']">{{valiDataForm.get('password')?.errors?.['msg']}}</p>
<br>
<label>
手机号: <input type="text" formControlName="phone">
</label>
<p *ngIf="valiDataForm.get('phone')?.errors?.['msg']">{{valiDataForm.get('phone')?.errors?.['msg']}}</p>
<br>
<button (click)="subvaliDataFormFun()">提交</button>
</form>