在 Angular 6 中创建用于跨字段验证(确认密码)的自定义指令

Posted

技术标签:

【中文标题】在 Angular 6 中创建用于跨字段验证(确认密码)的自定义指令【英文标题】:Creating a custom directive for cross field validation(confirm password) in angular 6 【发布时间】:2019-01-06 09:00:02 【问题描述】:

我创建了一个组件(set-pass),我想在这个组件中执行密码并确认密码活动。我已经通过在共享文件夹中创建自定义指令(confirm-equal-validator.directive.ts)来尝试它.

以下是我的组件文件

set-pass.component.html

    <form >
      <mat-form-field >
        <input matInput name="password" placeholder="New password" [type]="hide ? 'password' : 'text'" [formControl]="passFormControl" required>

        <mat-icon matSuffix (click)="hide = !hide">hide ? 'visibility' : 'visibility_off'</mat-icon>
        <mat-error *ngIf="passFormControl.hasError('required')">
            Please enter your newpassword
          </mat-error>
      </mat-form-field>

      <mat-form-field >
        <input matInput name="confirmPassword"  appConfirmEqualValidator="password"  placeholder="Confirm password" [type]="hide ? 'password' : 'text'" [formControl]="confirmFormControl" #confirmPasswordControl="ngModel" required>

        <mat-icon matSuffix (click)="hide = !hide">hide ? 'visibility' : 'visibility_off'</mat-icon>
        <mat-error *ngIf="confirmFormControl.hasError('required')">
          Confirm your password
          </mat-error>
          <mat-error *ngIf="confirmFormControl.hasError('notEqual')">
            Confirm your password
            </mat-error>
      </mat-form-field>
   </form>

set-pass.component.ts

    import Component, OnInit  from '@angular/core';
    import FormControl, FormGroupDirective, NgForm, Validators from 
         '@angular/forms';
    import ErrorStateMatcher from '@angular/material/core';

     @Component(
       selector: 'ylb-set-pass',
       templateUrl: './set-pass.component.html',
       styleUrls: ['./set-pass.component.css']
       )
     export class SetPassComponent 

        passFormControl = new FormControl('', [
        Validators.required,
         ]);
           confirmFormControl = new FormControl('', [
          Validators.required,
        ]);
   

confirm-equal-validator.directive.ts(存在于共享文件夹中)

    import  Validator,AbstractControl,NG_VALIDATORS  from '@angular/forms';
    import  Directive,Input from '@angular/core';



    @Directive(
       selector: '[appConfirmEqualValidator]',
       providers: [
            provide: NG_VALIDATORS,
            useExisting: ConfirmEqualValidatorDirective ,
            multi:true
        ]
     )

   export class ConfirmEqualValidatorDirective implements Validator
     @Input() appConfirmEqualValidator:string;
      validate(control: AbstractControl):[key:string]:any | null
        const controlToCompare = 
    control.parent.get(this.appConfirmEqualValidator);
        if(controlToCompare && controlToCompare.value !== control.value)
           return'notEqual':true;
         
         return null;
       
     

我已经像这样在 app.module.ts 中导入了这个组件

    import  ConfirmEqualValidatorDirective  from './shared/confirm-equal-validator.directive';

我已正确执行此视频中给出的每个步骤

    https://www.youtube.com/watch?v=YhazkQd59Hk

在 CMD 中出现此错误

    ERROR in src/main.ts(5,29): error TS2307: Cannot find module './environments/environment'.

我只想通过材质组件来实现密码确认, 像这样

【问题讨论】:

这与您的组件中导入环境文件的自定义指令无关,这就是它显示此错误的原因 我没有导入任何环境文件 打开 main.ts 并检查您的导入。 是的,它已经像这样导入 import AppModule from './app/app.module'; 我应该删除这条路径吗? 【参考方案1】:

抛开您的错误,有一种更简单的方法可以检查密码是否匹配。

假设你有两个像你一样的表单控件:

<input matInput name="password" placeholder="New password" [formControl]="passFormControl" required (blur)="checkPasswordControls()">
<input matInput name="password" placeholder="Confirm password" [formControl]="confirmFormControl" required (blur)="checkPasswordControls()">
checkPasswordControls() 
  if (this.passFormControl.value !== this.confirmFormControl.value) 
    this.passFormControl.setErrors( notEqual: true );
    this.confirmFormControl.setErrors( notEqual: true );
   else 
    this.passFormControl.setErrors(this.passFormControl.errors ?  ...this.passFormControl.errors  : null);
    this.confirmFormControl.setErrors(this.confirmFormControl.errors ?  ...this.confirmFormControl.errors  : null);
  

现在,每次您离开任一输入时,您的组件都会检查两个表单的值是否匹配:如果不匹配,它将在两个输入上设置错误。

这允许你删除你的指令(因为你只使用一次这个指令,你不需要指令),更短的阅读,更清晰,更容易理解。

【讨论】:

优雅而简约的解决方案。【参考方案2】:

找不到模块 './environments/environment' 检查当前目录中是否有任何名为 environment 的文件夹,即 ..,src>app>environment>environment.ts,environment.prod.ts 问题是您的主模块依赖于环境文件夹并且它不存在,大多数情况下,如果您使用 vscode 或其他一些智能编辑器,未解决的目录错误会在编辑器本身中被拾取。

【讨论】:

src>app中没有这样的文件 然后评论这一行。

以上是关于在 Angular 6 中创建用于跨字段验证(确认密码)的自定义指令的主要内容,如果未能解决你的问题,请参考以下文章

密码和确认密码字段验证 angular2 反应形式

在nodejs中创建API Key并验证跨域

JavaScript 中创建三种消息框:警告框确认框提示框。

在 AngularJS 中创建一个简单的引导是/否确认或只是通知警报

在 Angular 6 + 节点 js 中使用令牌的身份验证问题

在 Angular 和 mongoose 中创建包含嵌套数据的表