winform窗体模板
介绍 (Introduction)
In this article, we will learn about validations in Angular template-driven forms. We will create a simple user registration form and implement some inbuilt validations on it. Along with the inbuilt validations, we will also implement some custom validations for the template-driven form.
在本文中,我们将学习Angular模板驱动形式的验证。 我们将创建一个简单的用户注册表单,并在其上实现一些内置的验证。 除了内置的验证,我们还将为模板驱动的表单实现一些自定义验证。
We will consider the following custom validations for this demo:
我们将为此演示考虑以下自定义验证:
- Checking for user name availability 检查用户名可用性
- Password pattern validation 密码模式验证
- Matching the password entered in two different fields 匹配在两个不同字段中输入的密码
Take a look at the application in action.
看一下实际的应用程序。
先决条件 (Prerequisites)
Install Visual Studio code from here
从这里安装Visual Studio代码
Install the latest version of Angular CLI from here
从此处安装最新版本的Angular CLI
Install the latest LTS version of Node.js from here
从此处安装最新的LTS版本的Node.js
源代码 (Source Code)
You can get the source code from GitHub.
您可以从GitHub获取源代码。
创建Angular应用 (Create the Angular app)
Navigate to the folder where you want to create your project file. Open a command window and run the command shown below:
导航到要在其中创建项目文件的文件夹。 打开命令窗口并运行以下命令:
ng new angular-forms-validation --routing=false --style=scss
We are specifying the command to create a new Angular application. The option to create the routing module is set to false and style files extension is set to SCSS. This command will create the Angular project with the name angular-forms-validation.
我们正在指定创建新Angular应用程序的命令。 创建路由模块的选项设置为false,样式文件扩展名设置为SCSS。 此命令将使用名称angular-forms-validation创建Angular项目。
Change directories to the new project and open the project in VS Code using the set of commands below:
将目录更改为新项目,并使用以下命令集在VS Code中打开项目:
cd angular-forms-validation
code .
安装引导程序 (Install Bootstrap)
Run the following command to install Bootstrap:
运行以下命令以安装Bootstrap:
npm install bootstrap --save
Add the following import definition in the styles.scss
file:
在styles.scss
文件中添加以下导入定义:
@import "~bootstrap/dist/css/bootstrap.css";
创建验证服务 (Create the validation service)
Run the following command to create a new service:
运行以下命令以创建新服务:
ng g s services\customvalidation
This command will create a folder named services that has two files inside it – customvalidation.service.ts
and customvalidation.service.spec.ts
. Open customvalidation.service.ts
and put the following code inside it:
此命令将创建一个名为services的文件夹,其中有两个文件– customvalidation.service.ts
和customvalidation.service.spec.ts
。 打开customvalidation.service.ts
并将以下代码放入其中:
import { Injectable } from '@angular/core';
import { ValidatorFn, AbstractControl } from '@angular/forms';
import { FormGroup } from '@angular/forms';@Injectable({providedIn: 'root'
})
export class CustomvalidationService {patternValidator(): ValidatorFn {return (control: AbstractControl): { [key: string]: any } => {if (!control.value) {return null;}const regex = new RegExp('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}$');const valid = regex.test(control.value);return valid ? null : { invalidPassword: true };};}MatchPassword(password: string, confirmPassword: string) {return (formGroup: FormGroup) => {const passwordControl = formGroup.controls[password];const confirmPasswordControl = formGroup.controls[confirmPassword];if (!passwordControl || !confirmPasswordControl) {return null;}if (confirmPasswordControl.errors && !confirmPasswordControl.errors.passwordMismatch) {return null;}if (passwordControl.value !== confirmPasswordControl.value) {confirmPasswordControl.setErrors({ passwordMismatch: true });} else {confirmPasswordControl.setErrors(null);}}}userNameValidator(userControl: AbstractControl) {return new Promise(resolve => {setTimeout(() => {if (this.validateUserName(userControl.value)) {resolve({ userNameNotAvailable: true });} else {resolve(null);}}, 1000);});}validateUserName(userName: string) {const UserList = ['ankit', 'admin', 'user', 'superuser'];return (UserList.indexOf(userName) > -1);}
}
The method patternValidator
is used to validate the password pattern in our form. The parameter for this method is of type AbstractControl
which is a base class for the FormControl
.
patternValidator
方法用于验证表单中的密码模式。 此方法的参数类型为AbstractControl
,它是FormControl
的基类。
We will use a regular expression to validate the password. This regular expression will check for the following four conditions in the password:
我们将使用正则表达式来验证密码。 此正则表达式将检查密码中的以下四个条件:
- The password should be a minimum of eight characters long 密码长度至少为八个字符
- It should have at least one lower case letter 至少应有一个小写字母
- It should have at least one upper case letter 它应该至少包含一个大写字母
- It should have at least one number 它应该至少有一个数字
If the password fails the regex check, we will set the invalidPassword
property to true.
如果密码未通过正则表达式检查,我们会将invalidPassword
属性设置为true。
The method MatchPassword
is used to compare the passwords in two fields. This method will accept two parameters of type string. These parameters represent the name of the fields to be matched. We will get the FormControl
for these two fields and then match the values in them. If the values do not match, we will set the passwordMismatch
property to true.
MatchPassword
方法用于比较两个字段中的密码。 此方法将接受两个字符串类型的参数。 这些参数表示要匹配的字段的名称。 我们将获得这两个字段的FormControl
,然后匹配它们中的值。 如果值不匹配,我们将passwordMismatch
属性设置为true。
The method userNameValidator
is used to verify if the username is already taken or not. This method will accept a parameter of type AbstractControl
.
方法userNameValidator
用于验证用户名是否已被使用。 此方法将接受类型为AbstractControl
的参数。
We will check if the value of this field is present in a static array, UserList. If the value entered by the user is already present, we will set the userNameNotAvailable
property to true.
我们将检查此字段的值是否存在于静态数组UserList中。 如果用户输入的值已经存在,则将userNameNotAvailable
属性设置为true。
We are using the setTimeout function to invoke this check every two seconds. This will ensure that the error will be thrown after two seconds from the time the user stops typing in the field.
我们正在使用setTimeout函数每两秒钟调用一次此检查。 这将确保从用户停止在该字段中键入内容起两秒钟后将引发该错误。
For the sake of simplicity of this article, we are using a static array to search for the availability of user names. Ideally, it should be a service call to the server to search for the value in a database.
为了简化本文,我们使用静态数组来搜索用户名的可用性。 理想情况下,应该是对服务器的服务调用,以在数据库中搜索值。
创建用户模型 (Create the User model)
Create a new folder called models inside the src/app
folder. Add a new file called user.ts
inside the models folder. Put the following code in the user.ts
file.
在src/app
文件夹中创建一个名为models的新文件夹。 在models文件夹中添加一个名为user.ts
的新文件。 将以下代码放入user.ts
文件中。
export class User {public name: string;public email: string;public username: string;public password: string;public confirmPassword: string;
}
创建自定义指令 (Create custom directives)
We will create custom directives to implement custom validators for template-driven forms.
我们将创建自定义指令,以为模板驱动的表单实现自定义验证器。
Run the command shown below to create the passwordPattern
directive:
运行下面显示的命令以创建passwordPattern
指令:
ng g d directives\passwordPattern
This command will create a folder named directives that has two files inside it – passwordPattern.directive.ts
and passwordPattern.directive.spec.ts
. Open passwordPattern.directive.ts
and put the following code inside it.
此命令将创建一个名为指令的文件夹,其中有两个文件– passwordPattern.directive.ts
和passwordPattern.directive.spec.ts
。 打开passwordPattern.directive.ts
并将以下代码放入其中。
import { Directive } from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
import { CustomvalidationService } from '../services/customvalidation.service';@Directive({selector: '[appPasswordPattern]',providers: [{ provide: NG_VALIDATORS, useExisting: PasswordPatternDirective, multi: true }]
})
export class PasswordPatternDirective implements Validator {constructor(private customValidator: CustomvalidationService) { }validate(control: AbstractControl): { [key: string]: any } | null {return this.customValidator.patternValidator()(control);}
}
This directive is used to validate the password pattern. We will implement the Validator interface on the class PasswordPatternDirective
. We will override the validate method which accepts a parameter of type AbstractControl
, that is the control we want to validate. We will then invoke the patternValidator
method from the service.
此伪指令用于验证密码模式。 我们将在类PasswordPatternDirective
上实现Validator接口。 我们将覆盖validate方法,该方法接受类型为AbstractControl
的参数,这是我们要验证的控件。 然后,我们将从服务中调用patternValidator
方法。
Run the command shown below to create the matchPassword
directive:
运行以下所示的命令以创建matchPassword
指令:
ng g d directives\matchPassword
Open matchPassword.directive.ts
and put the following code inside it:
打开matchPassword.directive.ts
并将以下代码放入其中:
import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, ValidationErrors, FormGroup } from '@angular/forms';
import { CustomvalidationService } from '../services/customvalidation.service';@Directive({selector: '[appMatchPassword]',providers: [{ provide: NG_VALIDATORS, useExisting: MatchPasswordDirective, multi: true }]
})
export class MatchPasswordDirective implements Validator {@Input('appMatchPassword') MatchPassword: string[] = [];constructor(private customValidator: CustomvalidationService) { }validate(formGroup: FormGroup): ValidationErrors {return this.customValidator.MatchPassword(this.MatchPassword[0], this.MatchPassword[1])(formGroup);}
}
This directive is used to validate if the passwords entered in two fields are matching or not. This directive will accept an input of the type string array, which contains the fields to match. We will override the validate method and pass the parameter of type FormGroup
. We will then invoke the MatchPassword
method from the service.
此伪指令用于验证在两个字段中输入的密码是否匹配。 该指令将接受类型为字符串数组的输入,其中包含要匹配的字段。 我们将覆盖validate方法,并传递FormGroup
类型的参数。 然后,我们将从服务中调用MatchPassword
方法。
Run the command shown below to create the validateUserName
directive:
运行下面显示的命令以创建validateUserName
指令:
ng g d directives\validateUserName
Open validateUserName.directive.ts
and put the following code inside it:
打开validateUserName.directive.ts
并将以下代码放入其中:
import { Directive, forwardRef } from '@angular/core';
import { Validator, AbstractControl, NG_ASYNC_VALIDATORS } from '@angular/forms';
import { CustomvalidationService } from '../services/customvalidation.service';
import { Observable } from 'rxjs';@Directive({selector: '[appValidateUserName]',providers: [{ provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => ValidateUserNameDirective), multi: true }]})
export class ValidateUserNameDirective implements Validator {constructor(private customValidator: CustomvalidationService) { }validate(control: AbstractControl): Promise<{ [key: string]: any }> | Observable<{ [key: string]: any }> {return this.customValidator.userNameValidator(control);}
}
This directive is used to validate the availability of the user name. We will override the validate method and pass the parameter of type AbstractControl
. We will then invoke the userNameValidator
method from the service. This method will return a promise.
该伪指令用于验证用户名的可用性。 我们将覆盖validate方法并传递类型AbstractControl
的参数。 然后,我们将从服务中调用userNameValidator
方法。 此方法将返回一个承诺。
创建模板驱动的表单组件 (Create the template-driven form component)
Run the command shown below to create the template-driven-form component:
运行下面显示的命令以创建模板驱动表单组件:
ng g c template-driven-form
Open template-driven-form.component.ts
and put the following code in it:
打开template-driven-form.component.ts
并将以下代码放入其中:
import { Component } from '@angular/core';
import { User } from '../models/user';@Component({selector: 'app-template-driven-form',templateUrl: './template-driven-form.component.html',styleUrls: ['./template-driven-form.component.scss']
})
export class TemplateDrivenFormComponent {userModal = new User();constructor() { }onSubmit() {alert('Form Submitted succesfully!!!\n Check the values in browser console.');console.table(this.userModal);}
}
We have created an object userModal
of type User. We will bind the form fields with the property of this object. The onSubmit
method will show the success message on the screen and print the contents of the form to the console.
我们已经创建了类型为User的对象userModal
。 我们将表单域与该对象的属性绑定。 onSubmit
方法将在屏幕上显示成功消息,并将表单内容打印到控制台。
Open template-driven-form.component.html
and put the following code in it:
打开template-driven-form.component.html
并将以下代码放入其中:
<div class="container"><div class="row"><div class="col-md-8 mx-auto"><div class="card"><div class="card-header"><h3>Angular Template-driven Form</h3></div><div class="card-body"><form class="form" #registerForm="ngForm" [appMatchPassword]="['password', 'confirmPassword']"(ngSubmit)="registerForm.form.valid && onSubmit()" novalidate><div class=" form-group"><label>Name</label><input type="text" class="form-control" [(ngModel)]="userModal.name" name="name"#name="ngModel" required><span class="text-danger"*ngIf="(name.touched || registerForm.submitted) && name.errors?.required">Name is required</span></div><div class="form-group"><label>Email</label><input type="text" class="form-control" [(ngModel)]="userModal.email" name="email"#email="ngModel" required email><span class="text-danger"*ngIf="(email.touched || registerForm.submitted) && email.errors?.required">Email is required</span><span class="text-danger" *ngIf="email.touched && email.errors?.email">Enter a valid email address</span></div><div class="form-group"><label>User Name</label><input type="text" class="form-control" [(ngModel)]="userModal.username" name="username"#username="ngModel" appValidateUserName required><span class="text-danger"*ngIf="(username.touched || registerForm.submitted) && username.errors?.required">User Name is required</span><span class="text-danger" *ngIf="username.touched && username.errors?.userNameNotAvailable">User Name not available</span></div><div class="form-group"><label>Password</label><input type="password" class="form-control" [(ngModel)]="userModal.password" name="password"#password="ngModel" appPasswordPattern required><span class="text-danger"*ngIf="(password.touched || registerForm.submitted) && password.errors?.required">Password is required</span><span class="text-danger" *ngIf="password.touched && password.errors?.invalidPassword">Password should have minimum 8 characters, at least 1 uppercase letter, 1 lowercaseletter and 1 number</span></div><div class="form-group"><label>Confirm Password</label><input type="password" class="form-control" [(ngModel)]="userModal.confirmPassword"name="confirmPassword" #confirmPassword="ngModel" required><span class="text-danger"*ngIf="(confirmPassword.touched || registerForm.submitted) && confirmPassword.errors?.required">Confirm Password is required</span><span class="text-danger"*ngIf="confirmPassword.touched && confirmPassword.errors?.passwordMismatch">Passwords doesnot match</span></div><div class="form-group"><button type="submit" class="btn btn-success">Register</button></div></form></div></div></div></div>
</div>
We will create a template-driven form and use the Bootstrap card for styling. The card header will contain a title whereas the card body will have the form fields.
我们将创建一个模板驱动的表单,并使用Bootstrap卡进行样式设置。 卡片标题将包含标题,而卡片正文将具有表单字段。
We will use the appMatchPassword
directive on our form and pass the password and confirmPassword
fields for validation. The ngModel
property is used to bind the form control to the model.
我们将在appMatchPassword
上使用appMatchPassword
指令,并传递密码和confirmPassword
字段进行验证。 ngModel
属性用于将表单控件绑定到模型。
For validating the user name availability we will use the appValidateUserName
directive on the username field. Similarly, we will use the appPasswordPattern
directive on the password field to validate the password pattern.
为了验证用户名的可用性,我们将在用户名字appValidateUserName
上使用appValidateUserName
指令。 同样,我们将在密码字段上使用appPasswordPattern
指令来验证密码模式。
We will check for the errors in the form controls and then display the appropriate validation error message on the screen.
我们将检查表单控件中的错误,然后在屏幕上显示相应的验证错误消息。
创建导航栏组件 (Create the nav-bar component)
Run the command shown below to create the nav-bar component:
运行下面显示的命令以创建导航栏组件:
ng g c nav-bar
Open nav-bar.component.html
and put the following code in it:
打开nav-bar.component.html
并将以下代码放入其中:
<nav class="navbar navbar-expand-sm navbar-dark bg-dark fixed-top"><a class="navbar-brand" [routerLink]='["/"]'>Form Validation Demo</a><div class="collapse navbar-collapse"><ul class="navbar-nav mr-auto"><li class="nav-item"><a class="nav-link" [routerLink]='["/template-form"]'>Template Form</a></li></ul></div>
</nav>
Here we are adding the navigation link to the template-driven form component.
在这里,我们将导航链接添加到模板驱动的表单组件。
更新应用程序组件 (Update the app component)
Open the app.component.html
file and put the following code in it:
打开app.component.html
文件,并将以下代码放入其中:
<app-nav-bar></app-nav-bar>
<div class="container"><router-outlet></router-outlet>
</div>
更新应用程序模块 (Update the App module)
We will import the forms module and also set up the routing for our application in the app module. Add the following code in the app.module.ts
file. You can refer to GitHub for the complete source code of this file:
我们将导入表单模块,并在app模块中为我们的应用程序设置路由。 在app.module.ts
文件中添加以下代码。 您可以参考GitHub以获得此文件的完整源代码:
import { RouterModule } from '@angular/router';
import { FormsModule } from '@angular/forms';@NgModule({... imports: [...FormsModule,RouterModule.forRoot([{ path: '', component: TemplateDrivenFormComponent },{ path: 'template-form', component: TemplateDrivenFormComponent }]),],
})
执行演示 (Execution demo)
Use the following command to start the webserver:
使用以下命令启动网络服务器:
ng serve -o
This command will launch the application in your default browser at http://localhost:4200/
. You can perform all the form validations which we have discussed here.
此命令将在您的默认浏览器http://localhost:4200/
启动应用程序。 您可以执行我们在此处讨论的所有表单验证。
This application is also hosted at https://ng-forms-validation.herokuapp.com/. Navigate to the link and play around with it for a better understanding.
此应用程序还托管在https://ng-forms-validation.herokuapp.com/上 。 导航至该链接,并对其进行处理以更好地理解。
摘要 (Summary)
We have created a sample user registration form using the template-driven form approach in Angular. We have implemented the inbuilt validations as well as custom validations to the form. The Bootstrap library is used to style the form.
我们使用Angular中的模板驱动表单方法创建了一个示例用户注册表单。 我们已经实现了表单的内置验证以及自定义验证。 Bootstrap库用于设置表单样式。
Get the source code from GitHub and play around with it for a better understanding.
从GitHub获取源代码并试用它,以更好地理解。
也可以看看 (See Also)
Reactive Form Validation In Angular
Angular的React形式验证
Localization In Angular Using i18n Tools
使用i18n工具在Angular中进行本地化
Policy-Based Authorization In Angular Using JWT
使用JWT在Angular中基于策略的授权
ASP.NET Core – Using Highcharts With Angular 5
ASP.NET Core –在Angular 5中使用Highcharts
ASP.NET Core – CRUD Using Angular And Entity Framework Core
ASP.NET Core –使用Angular和Entity Framework Core的CRUD
You can find this post Template-Driven Form Validation In Angular and others like it on Ankit Sharma's Blog.
您可以在Ankit Sharma的Blog上找到这篇文章Angular中的模板驱动表单验证和其他类似文章 。
翻译自: https://www.freecodecamp.org/news/how-to-validate-angular-template-driven-forms/
winform窗体模板