Как я могу получить переменные компонента в пользовательском валидаторе? - PullRequest
2 голосов
/ 08 июля 2019

Я хочу сделать пользовательский валидатор, который сделал бы кнопку отправки доступной, только если текст в форме уникален.У меня есть экземпляр VulnarabilitiesClass, который содержит массив объектов с полями id и name.После ввода любого текста в моей форме я получаю эту ошибку: Ошибка: undefined не является объектом (оценивает 'this.systemVulnarabilities')

<form [formGroup]="profileForm">
  <label>
    Vulnarability Name:
    <input type="text" formControlName="name" required>
  </label>
</form>

<p>
  Form Status: {{ profileForm.status }}
</p>
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<button type="submit" [disabled]="!profileForm.valid">Submit</button>
this.systemVulnarabilities = new VulnarabilitiesClass();

profileForm = this.fb.group({
    name: ['', Validators.required,this.UniqueNameValidator],
  });

private UniqueNameValidator(control: FormControl): ValidationErrors{
  let vulnarabilityName: string = control.value;
  console.log(vulnarabilityName);
  console.log(this.systemVulnarabilities.displayList.toString());//no output already
  let found: number = this.systemVulnarabilities.displayList.map(function(e) { return e.name; }).indexOf(vulnarabilityName); //mistake
  if(found === -1){
    return {invalidPassword: 'this name already exists'};
  }
  return null;
}

Ответы [ 3 ]

2 голосов
/ 08 июля 2019

Эта ошибка возникает из-за того, что метод UniqueNameValidator выполняется с отличным от контекста компонента this. Причина этого в том, что в контексте javascript this зависит от того, как выполняется функция, а не от того, где она была объявлена.

Простое исправление заключается в использовании Function.prototype.bind метода, который обеспечивает правильный контекст this

this.UniqueNameValidator.bind(this)

Кроме того, если ваш валидатор является синхронным, вам нужно заключить валидаторы в массив, иначе Angular будет рассматривать его как асинхронный валидатор:

name: ['', [Validators.required, this.UniqueNameValidator.bind(this)]],
1 голос
/ 08 июля 2019

другой "классический" способ - определить функцию, например

private UniqueNameValidator(){
  return (control: FormControl)=>{
         ....
  }
}

и добавить валидатор - см. () В конце UniqueNameValidator

profileForm = this.fb.group({
    name: ['', Validators.required,this.UniqueNameValidator()],
  });
0 голосов
/ 08 июля 2019

Я думаю, что вы могли бы использовать замыкание и сделать свой Validator контекстным с переменной systemVulnarabilities, например:


profileForm = this.fb.group({
    name: ['', Validators.required,this.UniqueNameValidator(systemVulnarabilities)],
  });

UniqueNameValidator(systemVulnarabilities): ValidatorFn {
  return (control: FormControl)=>{
    let vulnarabilityName: string = control.value;
  let found: number = systemVulnarabilities.displayList.map(function(e) { return e.name; }).indexOf(vulnarabilityName); //mistake
  if(found === -1){
    return {invalidPassword: 'this name already exists'};
  }
  return null;
  }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...