在 Angular 中实现共享自定义验证器指令





5.00/5 (2投票s)
如何在 Angular 5 中创建自定义验证器指令
引言
在这篇文章中,我们将学习如何在 Angular 5 中创建一个自定义验证器指令。我们已经在之前的文章中介绍了如何进行验证,但我们还没有做任何比较密码和确认密码的验证,还记得吗?在这里,我们将看到如何做到这一点。在本文结束时,您将了解如何根据我们的要求创建一个新的共享指令。这篇文章是 开发 Angular 5 应用程序 系列课程的延续。如果您还没有阅读过之前的文章,我强烈建议您这样做。您可以在下面找到指向之前文章的链接。我希望你会喜欢这篇文章。
开发 Angular 5 应用系列
这些是本系列的上一篇文章。请继续阅读。
- 什么是新的,以及如何设置我们的第一个 Angular 5 应用程序
- Angular 5 基本演示项目概述
- 在 Angular 5 应用中生成你的第一个组件和模块
- 在 Angular 5 应用中实现验证
- 在 Angular 5 中使用模板驱动表单进行验证
背景
验证在所有应用程序中都起着至关重要的作用,无论它使用何种语言开发。由于它是一个重要的部分,因此有很多方法可以实现它。如果我们创建一个自定义共享指令来创建比较验证器,那将是一段很棒的代码,可以重复使用。
Using the Code
建议从 GitHub 克隆项目,这样您就可以自己尝试所有操作。现在让我们开始编写一些代码。
创建自定义指令
让我们在共享文件夹中创建一个新指令,并将其命名为equal.validator.directive.ts。现在打开该文件并开始编写代码。让我们首先导入一些核心组件。
import { Validator, AbstractControl, NG_VALIDATORS } from "@angular/forms";
import { Directive, Input } from "@angular/core";
现在让我们定义我们的类和 @Directive
。
import { Validator, AbstractControl, NG_VALIDATORS } from "@angular/forms";
import { Directive, Input } from "@angular/core";
@Directive({
selector: "[appEqualValidator]",
providers: [{
provide: NG_VALIDATORS,
useExisting: EqualValidatorDirective,
multi: true
}]
})
export class EqualValidatorDirective implements Validator {
validate(c: AbstractControl): { [key: string]: any; } {
throw new Error("Method not implemented.");
}
registerOnValidatorChange?(fn: () => void): void {
throw new Error("Method not implemented.");
}
}
正如你所看到的,我们实际上是从 Validator 继承了我们的新类 EqualValidatorDirective
。现在,我们需要更改其中方法的实现。我们还应该在 app.module.ts 文件中添加我们的新指令。
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule} from '@angular/platform-browser/animations'
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { MatButtonModule, MatCardModule, MatInputModule, MatSnackBarModule, MatToolbarModule }
from '@angular/material';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { EqualValidatorDirective } from './shared/equal.validator.directive';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { NavComponent } from './nav/nav.component';
import { RegistrationComponent } from './registration/registration.component';
import { LoginComponent } from './login/login.component';
import { AuthService } from './auth.service';
import { AuthGuard } from './auth.guard';
const myRoots: Routes = [
{ path: '', component: HomeComponent, pathMatch: 'full' , canActivate: [AuthGuard]},
{ path: 'register', component: RegistrationComponent },
{ path: 'login', component: LoginComponent},
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard]}
];
@NgModule({
declarations: [
AppComponent,
HomeComponent,
NavComponent,
RegistrationComponent,
LoginComponent,
EqualValidatorDirective
],
imports: [
BrowserModule, BrowserAnimationsModule, FormsModule, ReactiveFormsModule,
MatButtonModule, MatCardModule, MatInputModule, MatSnackBarModule, MatToolbarModule,
RouterModule.forRoot(myRoots)
],
providers: [AuthService, AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }
实现 Validate
在我们这样做之前,我们应该在我们的确认密码字段中添加我们的新自定义指令选择器,因为这是我们将要使用我们的验证器的地方。因此,我们将更改我们的确认密码字段的标记,如下所示
<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"
appEqualValidator="password" placeholder="Confirm Password" [(ngModel)]="confirmPassword"
#confirmPasswordControl="ngModel">
<span class="help-block" *ngIf="confirmPasswordControl.errors?.required &&
confirmPasswordControl.touched">
Confirm password is required
</span>
</div>
正如你所看到的,我们正在我们的确认密码字段中使用选择器 appEqualValidator="password"
。如果您不确定如何实现其他验证(如电子邮件和必填项),请检查我之前的文章。
现在让我们回到我们的自定义指令并进行一些更改。
export class EqualValidatorDirective implements Validator {
@Input() appEqualValidator: string;
validate(c: AbstractControl): { [key: string]: any; } {
const controlToCompare = c.parent.get(this.appEqualValidator)
if (controlToCompare && controlToCompare.value == c.value)return { "equal": true };
return { "notEqual": true }
}
registerOnValidatorChange?(fn: () => void): void {
throw new Error("Method not implemented.");
}
}
在这里,我们在绝对控件 "c
" 中获得我们的 confirmPassword
控件,在下一行中,我们只是通过获取 confirmPassword
的 parent
元素来找到我们的密码控件。一旦我们得到它,我们就可以很容易地进行比较了,对吧?所以,如果它匹配,我们返回 { "equal": true };
否则返回 { "notEqual": true }
。 听起来不错?
为自定义消息引入新的 Span
现在我们有一个自定义验证器,它可以比较两个值,唯一缺少的是创建一个 span
以在 UI 中显示我们的新消息。现在让我们更改我们的标记。
<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"
appEqualValidator="password" placeholder="Confirm Password" [(ngModel)]="confirmPassword"
#confirmPasswordControl="ngModel">
<span class="help-block" *ngIf="confirmPasswordControl.errors?.required &&
confirmPasswordControl.touched">
Confirm password is required
</span>
<span class="help-block" *ngIf="confirmPasswordControl.errors?.notEqual
&& confirmPasswordControl.touched && !confirmPasswordControl.errors?.required">
Password doesn't match
</span>
</div>
正如你所看到的,只有当指令返回 notEqual
属性并且没有必需的错误时,我们才会显示自定义消息。让我们运行我们的应用程序,看看它的实际效果。
在这里,我们已经看到了如何实现共享的自定义验证器指令。让我们连接到数据库并在下一篇文章中保存这些值。在那之前,再见。
结论
非常感谢阅读。我是否遗漏了你认为需要的内容?你觉得这篇帖子有用吗?希望你喜欢这篇文章。请分享你宝贵的建议和反馈。
现在轮到你了。你有什么想法?
没有评论的博客不是博客,但请尽量保持在主题上。如果您有与这篇文章无关的问题,最好将其发布在 C# Corner、Code Project、Stack Overflow、ASP.NET Forum 上,而不是在此处发表评论。在 Twitter 或电子邮件中给我发送指向您在那里的问题的链接,如果我可以,我一定会尽力提供帮助。