// src/app/domain/index.ts
export interface User {
// 新的用户id一般由服务器自动生成,所以可以为空,用 ? 标示
id?: string;
email: string;
password: string;
repeat: string;
address: Address;
}
export interface Address {
province: string; // 省份
city: string; // 城市
area: string; // 区县
addr: string; // 详细地址
}
<!-- template-driven.component.html --> <form novalidate> <label> <span>电子邮件地址</span> <input type="text" name="email" placeholder="请输入您的 email 地址"> </label> <div> <label> <span>密码</span> <input type="password" name="password" placeholder="请输入您的密码"> </label> <label> <span>确认密码</span> <input type="password" name="repeat" placeholder="请再次输入密码"> </label> </div> <div > <label> <span>省份</span> <select name="province"> <option value="">请选择省份</option> </select> </label> <label> <span>城市</span> <select name="city"> <option value="">请选择城市</option> </select> </label> <label> <span>区县</span> <select name="area"> <option value="">请选择区县</option> </select> </label> <label> <span>地址</span> <input type="text" name="addr"> </label> </div> <button type="submit">注册</button> </form>
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from "@angular/forms";
import { TemplateDrivenComponent } from './template-driven/template-driven.component';
@NgModule({
imports: [
CommonModule,
FormsModule
],
exports: [TemplateDrivenComponent],
declarations: [TemplateDrivenComponent]
})
export class FormDemoModule { }
进行模版驱动类型的表单处理的一个必要步骤就是建立数据的双向绑定,那么我们需要在组件中建立一个类型为 User 的成员变量并赋初始值。
// template-driven.component.ts
// 省略元数据和导入的类库信息
export class TemplateDrivenComponent implements OnInit {
user: User = {
email: '',
password: '',
repeat: '',
address: {
province: '',
city: '',
area: '',
addr: ''
}
};
// 省略其他部分
}
<input type="text" name="email" placeholder="请输入您的 email 地址" ngModel>
<!-- ngForm 并不需要显示声明,任何 <form> 标签默认都是 ngForm --> <form novalidate ngForm> <input type="text" name="email" placeholder="请输入您的 email 地址" ngModel> </form>
<!-- 使用 # 把表单对象导出到 f 这个可引用变量中 -->
<form novalidate #f="ngForm">
...
</form>
<!-- 将表单的值以 JSON 形式输出 -->
{{f.value | json}}
user: User = {
email: 'wang@163.com',
...
};
<div>
<span>user: </span> {{user | json}}
</div>
<div>
<span>表单:</span> {{f.value | json}}
</div>
<input [(ngModel)]="user.email"> <input [ngModel]="user.email"` (ngModelChange)="user.email = $event">
<!-- 使用 ngModelGroup 来创建并绑定 FormGroup -->
<div ngModelGroup="address">
<label>
<span>省份</span>
<select name="province" (change)="onProvinceChange()" [(ngModel)]="user.address.province">
<option value="">请选择省份</option>
<option [value]="province" *ngFor="let province of provinces">{{province}}</option>
</select>
</label>
<!-- 省略其他部分 -->
</div>
<form novalidate #f="ngForm">
<label>
<span>电子邮件地址</span>
<input
type="text"
name="email"
placeholder="请输入您的 email 地址"
[ngModel]="user.email"
required
pattern="([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+.[a-zA-Z]{2,4}">
</label>
<div>
<label>
<span>密码</span>
<input
type="password"
name="password"
placeholder="请输入您的密码"
[(ngModel)]="user.password"
required
minlength="8">
</label>
<label>
<span>确认密码</span>
<input
type="password"
name="repeat"
placeholder="请再次输入密码"
[(ngModel)]="user.repeat"
required
minlength="8">
</label>
</div>
<!-- 省略其他部分 -->
<button type="submit" [disabled]="f.invalid">注册</button>
</form>
<div>
<div>
<span>email 验证:</span> {{f.controls.email?.errors | json}}
</div>
{
"pattern":
{
"requiredPattern": "^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+.[a-zA-Z]{2,4}$",
"actualValue": "w"
}
}
<label> <span>电子邮件地址</span> <input ... [ngModel]="user.email" #email="ngModel"> </label> <div *ngIf="email.errors?.required && email.touched" class="error"> email 是必填项 </div> <div *ngIf="email.errors?.pattern && email.touched" class="error"> email 格式不正确 </div>
<div> <label> <span>密码</span> <input type="password" name="password" placeholder="请输入您的密码" [(ngModel)]="user.password" required minlength="8" validateEqual="repeat"> </label> <label> <span>确认密码</span> <input type="password" name="repeat" placeholder="请再次输入密码" [(ngModel)]="user.repeat" required minlength="8"> </label> </div>
import { Directive, forwardRef } from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
@Directive({
selector: '[validateEqual][ngModel]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: forwardRef(()=>RepeatValidatorDirective),
multi: true
}
]
})
export class RepeatValidatorDirective implements Validator{
constructor() { }
validate(c: AbstractControl): { [key: string]: any } {
return null;
}
}
export class RepeatValidatorDirective implements Validator{
constructor(
@Attribute('validateEqual') public validateEqual: string,
@Attribute('reverse') public reverse: string) { }
private get isReverse() {
if (!this.reverse) return false;
return this.reverse === 'true' ? true: false;
}
validate(c: AbstractControl): { [key: string]: any } {
// 控件自身值
let self = c.value;
// 要对比的值,也就是在 validateEqual=“ctrlname” 的那个控件的值
let target = c.root.get(this.validateEqual);
// 不反向查询且值不相等
if (target && self !== target.value && !this.isReverse) {
return {
validateEqual: true
}
}
// 反向查询且值相等
if (target && self === target.value && this.isReverse) {
delete target.errors['validateEqual'];
if (!Object.keys(target.errors).length) target.setErrors(null);
}
// 反向查询且值不相等
if (target && self !== target.value && this.isReverse) {
target.setErrors({
validateEqual: true
})
}
return null;
}
}
<input type="password" name="password" placeholder="请输入您的密码" [(ngModel)]="user.password" #password="ngModel" required minlength="8" validateEqual="repeat" reverse="true"> <!-- 省略其他部分 --> <input type="password" name="repeat" placeholder="请再次输入密码" [(ngModel)]="user.repeat" #repeat="ngModel" required minlength="8" validateEqual="password" reverse="false">
<form novalidate #f="ngForm" (ngSubmit)="onSubmit(f, $event)">
onSubmit({value, valid}, event: Event){
if(valid){
console.log(value);
}
event.preventDefault();
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有