介绍
在这篇文章中,我们将看到如何在Angular 5中使用模板驱动的表单进行验证; 这只是一种可以遵循的不同方法,正如我们在前一篇文章中讨论的另一种方式。在本文结尾处,您将了解如何使用模板驱动表单在Angular 5应用程序中实现验证。本文是开发Angular 5 App系列的延续 ; 如果你还没有浏览以前的帖子,我强烈建议你这样做。您可以在下面找到以前帖子的链接。我希望你会喜欢这篇文章。
背景
验证在所有应用程序中都起着至关重要的作用,无论它以何种语言开发。由于它是一个重要部分,因此有很多方法可以实现它。我们将在这里看看模板驱动的表单方法。
使用代码
建议从GitHub克隆该项目,以便您可以尝试自己的一切。现在让我们继续写一些代码。
安装Bootstrap
在我们开始之前,让我们在我们的应用程序中安装bootstrap。
PS F:\My Projects\ng5> npm install bootstrap --save
在我们使用Angular CLI开发这个应用程序时,我们可以在我们的Angular-CLI.json文件中添加对Bootstrap的引用。添加引用后,该文件的样式部分将看起来像下面的代码。
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.min.css"
]
请注意,在我们的应用程序中还有很多其他的配置Bootstrap的方法,但是在这里解释它们已经超出了本文的范围。
将ngForm导入到变量
让我们清理我们的注册组件中的代码,并添加一个新的表单,其中有一个表单变量,它可以保存我们表单的值。有很多事情可以用这个变量来做,现在让我们假设它是我们的模型值容器。
<div class="container">
<div class="row">
<div class="no-float center-block col-lg-4 col-sm-4">
<mat-card>
<mat-card-header>
<img mat-card-avatar src="../../../assets/images/App-login-manager-icon.png">
<mat-card-title>Sign up</mat-card-title>
<mat-card-subtitle>Trust us for your data, and sign up</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<form #regsiterForm="ngForm" (ngSubmit)="register(regsiterForm)">
</form>
</mat-card-content>
</mat-card>
</div>
</div>
</div>
import { OnInit, Component } from "@angular/core";
@Component({
selector: 'app-registration',
templateUrl: './registration.component.html',
styleUrls: ['./registration.component.css']
})
export class RegistrationComponent implements OnInit {
constructor() {
}
ngOnInit() {
}
}
使用模板驱动的表单实现用户名字段的验证
正如我们创建了我们的表格,现在是时候为它生成输入控件了。
<form #regsiterForm="ngForm" (ngSubmit)="register(regsiterForm)">
<div class="signup-fields">
<div class="form-group">
<input type="text" required name="userName" class="form-control" placeholder="User Name">
</div>
<div>
<button class="btn btn-primary btn-block" type="submit">Signup</button>
</div>
</div>
</form>
我们上面的内容是用模板驱动的表单创建一个简单的HTML文档,我们将在其中介绍验证。我们userName 现在修改该 字段。
<input type="text" [(ngModel)]="userName" #userName="ngModel" required name="userName" class="form-control" placeholder="User Name">
我们试图通过上面的代码实现的是创造一个参考变量 userName,以及分配 input的值给它。基本上,这是一种双向绑定,我们可以从组件中设置数据并将其更新为表单,反之亦然。现在,如果你运行你的应用程序,你应该会看到类似下面的错误。
Uncaught Error: Cannot assign to a reference or variable!
at _AstToIrVisitor.visitPropertyWrite (compiler.js:26025)
at PropertyWrite.visit (compiler.js:4585)
at convertActionBinding (compiler.js:25475)
at eval (compiler.js:27987)
at Array.forEach (<anonymous>)
at ViewBuilder._createElementHandleEventFn (compiler.js:27983)
at nodes.(anonymous function) (webpack-internal:///./node_modules/@angular/compiler/esm5/compiler.js:27620:27)
at eval (compiler.js:27928)
at Array.map (<anonymous>)
at ViewBuilder._createNodeExpressions (compiler.js:27927)
这是因为我们对模型和参考变量都使用了相同的名称。所以我们应该改变这一点。为此,我们创建一个用户模型(user.model.ts)并在我们的注册组件中引用它。
export class User {
id: any;
userName: string;
email: string;
userRole: string;
profileImage: string;
phoneNumber: string;
firstName: string;
lastName: string;
}
import { User } from '../models/user.model'
现在我们可以改变我们的 input 如下所示。
<input type="text" [(ngModel)]="user.userName" #userName="ngModel" required name="userName" class="form-control" placeholder="User Name">
请确保在注册组件中声明一个用户。
export class RegistrationComponent implements OnInit {
user = new User();
constructor() {
}
ngOnInit() {
}
}
现在,如果您运行应用程序,则只有在表单有效时才会启用提交按钮,即只有在用户名字段中输入任何值时才会启用提交按钮。
装饰验证消息
现在我们知道我们的表单工作正常,但是如果他们没有在这些字段中给出任何值,我们不需要向用户发送消息?让我们在我们的HTML中添加更多的标记。
<div class="form-group" [class.has-error]="userName.invalid" [class.has-success]="userName.valid">
<input type="text" [(ngModel)]="user.userName" #userName="ngModel" required name="userName" class="form-control" placeholder="User Name">
<span class="help-block" *ngIf="userName.errors?.required">
User Name is required
</span>
</div>
我们正在动态启用这些类 has-error并 has-success 检查该userName 字段的有效和无效属性 。如果我们的userName 模型中有任何必需的错误,我们也会在新的时间范围内显示我们所需的现场信息 。现在,如果你运行你的应用程序,你可以看到验证工作正常。
但是,不是默认显示的验证?我们应该只显示消息,如果用户触及我们的领域,并拒绝输入任何内容,对吧?让我们加入userName.touched 我们的标记。
<div class="form-group" [class.has-error]="userName.invalid && userName.touched" [class.has-success]="userName.valid">
<input type="text" [(ngModel)]="user.userName" #userName="ngModel" required name="userName" class="form-control" placeholder="User Name">
<span class="help-block" *ngIf="userName.errors?.required && userName.touched">
User Name is required
</span>
</div>
对其他字段进行验证
现在是时候在我们的应用的其他领域实施验证。
<div class="container" style="margin-top:100px;">
<div class="row justify-content-center align-items-center">
<div class="col-lg-4 col-sm-4 center-block ">
<mat-card>
<mat-card-header>
<img mat-card-avatar src="../../../assets/images/App-login-manager-icon.png">
<mat-card-title>Sign up</mat-card-title>
<mat-card-subtitle>Trust us for your data, and sign up</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<form #regsiterForm="ngForm" (ngSubmit)="register(user)">
<div class="signup-fields">
<div class="form-group" [class.has-error]="userName.invalid && userName.touched" [class.has-success]="userName.valid">
<input type="text" [(ngModel)]="user.userName" #userName="ngModel" required name="userName" class="form-control" placeholder="User Name">
<span class="help-block" *ngIf="userName.errors?.required && userName.touched">
User Name is required
</span>
</div>
<div class="form-group" [class.has-error]="email.invalid && email.touched" [class.has-success]="email.valid">
<input type="text" required [email]="user.email !== ''" [(ngModel)]="user.email" name="email" class="form-control" placeholder="Email"
#email="ngModel">
<span class="help-block" *ngIf="email.errors?.required && email.touched">
Email is required
</span>
<span class="help-block" *ngIf="email.errors?.email && email.touched">
Email is invalid
</span>
</div>
<div class="form-group" [class.has-error]="password.invalid && password.touched" [class.has-success]="password.valid">
<input type="password" [(ngModel)]="user.password" required class="form-control" name="password" placeholder="Password" #password="ngModel">
<span class="help-block" *ngIf="password.invalid && password.touched">
Password is required
</span>
</div>
<div class="form-group" [class.has-error]="confirmPasswordControl.invalid && confirmPasswordControl.touched" [class.has-success]="confirmPasswordControl.valid">
<input type="password" required class="form-control" name="confirmPassword" placeholder="Confirm Password" [(ngModel)]="confirmPassword"
#confirmPasswordControl="ngModel">
<span class="help-block" *ngIf="confirmPasswordControl.errors?.required && confirmPasswordControl.touched">
Confirm password is required
</span>
</div>
<div>
<button class="btn btn-primary btn-block" type="submit" [disabled]="regsiterForm.invalid">Signup</button>
</div>
</div>
</form>
</mat-card-content>
</mat-card>
</div>
</div>
</div>
对于电子邮件验证,我们已经给出了一个额外的属性并将条件设置为[email]="user.email !== ""; ?他使得它使得所需的验证和验证电子邮件不会被一起显示。如果用户触摸该字段并且没有给出任何值,这将显示所需的消息,并且只有当输入的值不是有效的电子邮件时,电子邮件验证才会被触发。听起来不错,对吧?
添加注册功能
最后,让我们添加我们的 register 功能。
import { OnInit, Component } from "@angular/core";
import { User } from '../models/user.model';
@Component({
selector: 'app-registration',
templateUrl: './registration.component.html',
styleUrls: ['./registration.component.css']
})
export class RegistrationComponent implements OnInit {
user = new User();
constructor() {
}
ngOnInit() {
}
register(user: User): void{
console.log(user);
}
}
一旦完成,我们打开浏览器控制台并查看数据。
在这里我们已经看到了我们如何使用模板驱动的表单来实现验证。我将在Angular中使用指令编写我的下一篇关于实现自定义验证器的文章,以便我们可以比较我们的密码并确认密码字段。
结论
非常感谢您的阅读。我错过任何你认为需要的东西吗?你觉得这篇文章有用吗?我希望你喜欢这篇文章。请与我分享您的宝贵建议和反馈。