我在指令中注入的共享数据未定义

I am getting undefined for the shared data injected in a directive

所以我试图将共享数据注入一个指令,供验证器用来验证用户输入的电子邮件。我的问题是我从指令内部获取共享数据的值 'undefined'。以下是片段:

registration.html

  div class="form-group md-form" [class.has-error]="email.touched && email.dirty && email?.errors?.emailExist">
    <i class="fa fa-envelope prefix grey-text"></i>
    <input type="email" name="email" id="email" email="true" appCheckEmail [(ngModel)]="dealerRegistrationInput.email" #email="ngModel" class="form-control" placeholder="Email Address">
     <div class="help-block alert alert-danger " *ngIf="email.errors && (email.dirty || email.touched) && email?.errors?.emailExist">
     <div [hidden]="!email.errors.email">
      A valid email is required.
     </div>
    <div [hidden]="email?.errors.emailExist">
      This email address already exist
    </div>
   </div>
  </div>

registration.ts

.......
 constructor(
    private router: Router,
    private route:  ActivatedRoute,
    private http: HttpClient,
    private sharedData: SharedDataService,
    private connectService: ConnectService,
    private modalService: BsModalService) { }

  ngOnInit() {
     this.connectService.getAllDealers().subscribe((dealers: Dealer[]) => {
      this.sharedData.dealers  = dealers;
      console.log('Dealers.....' + JSON.stringify(this.sharedData.dealers));
    });
  }
 ............
 .........
 .............

检查邮件指令

    import {  Input, Directive, forwardRef } from '@angular/core';
    import { Validator, FormControl, AbstractControl, NG_VALIDATORS, ValidationErrors } from '@angular/forms';
    import { SharedDataService } from './shared-data.service';


    /* ......Functions.........................*/

      function appCheckEmail(dealersEmails: string[]) {
console.log('Dealers..:   ' + JSON.stringify(dealersEmails)); //THIS IS UNDEFINED
           return (control: AbstractControl) => {
  console.log('Dealers email addresses2:   ' + JSON.stringify(dealersEmails));
  console.log('Control value: ' + control.value)
  ...

  ...
      if (dealersEmails.indexOf(control.value) >= 0) {
                   return null;
           } else {
              return{  emailnotExist: true  };
           }
        };
       }

     /* -------------------------End of Functions.............*/

    @Directive({
      selector: '[appCheckEmail][ngModel], [appCheckEmail][ngModel]',
      providers: [{
        provide: NG_VALIDATORS,
        useExisting: forwardRef(() => CheckEmailDirective),
        multi: true
      }]
    })

    export class CheckEmailDirective implements Validator {
      validator: Function;

      constructor(private sharedData: SharedDataService) {

      this.validator = appCheckEmail(sharedData.dealers); /* sharedData.dealers is undefined */
         }
         validate(control: AbstractControl): ValidationErrors | null {
            return this.validator(control);
          }

        }

尽管注入未指向正确的引用或值已被清除,但指令中的共享数据不知何故。 我还观察到一些非常奇怪的事情......一旦呈现 html 就会执行 checkMail 指令......在输入任何数据之前并且显然在目标输入字段的每次击键上......这种行为是否会导致问题? 如果能得到任何帮助,我将不胜感激。

--编辑-- 将 appCheckEmail 参数更改为 appCheckEmail(sharedData:SharedDataService)

和 indexOf 搜索到:

 if (sharedData.dealers.indexOf(control.value) >= 0){....}

搜索仍然找不到匹配项。我已经用 console.log 确认 sharedData.dealers 数组实际上是一个字符串数组,而 control.value 是一个包含我期望的值的字符串。我还尝试了简单的 for 循环:

if(sharedData.dealers[i] === control.value) 我什至试过: 如果(sharedData.dealers[i] === 'emailinarray@mail.com')

并且都失败了。我知道我在这里缺少一些基本的东西,但我似乎找不到它。难道我在构造函数中传递了引用,sharedData.dealers[i] 仍然指向错误的地方?

您不应将 dealers 传递给验证函数,而应将对您的服务的引用传递给该函数。您的解决方案的问题在于 dealers 不存在于 constructor 中。您正在异步获取 Component 中的 dealers,因此它们在 Directive 构造函数

的构建期间不存在

import {  Input, Directive, forwardRef } from '@angular/core';
import { Validator, FormControl, AbstractControl, NG_VALIDATORS, ValidationErrors } from '@angular/forms';
import { SharedDataService } from './shared-data.service';


/* ......Functions.........................*/

function appCheckEmail(sharedData: SharedDataService) {

  return (control: AbstractControl) => {
    console.log('Dealers email addresses2:   ' + JSON.stringify(sharedData.dealersEmails));
    console.log('Control value: ' + control.value)
    ...

    ...
    if (sharedData.dealersEmails.indexOf(control.value) >= 0) {
      return null;
     } else {
      return{  emailnotExist: true  };
    }
  };
}

/* -------------------------End of Functions.............*/

@Directive({
  selector: '[appCheckEmail][ngModel], [appCheckEmail][ngModel]',
  providers: [{
    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => CheckEmailDirective),
    multi: true
  }]
})
export class CheckEmailDirective implements Validator {
  validator: Function;

  constructor(private sharedData: SharedDataService) {
    this.validator = appCheckEmail(sharedData); /* sharedData.dealers is undefined */
  }
  
  validate(control: AbstractControl): ValidationErrors | null {
    return this.validator(control);
  }

}