пользовательский валидатор в ошибке результатов таблицы материалов angular4 - PullRequest
1 голос
/ 26 февраля 2020

Я использую angular4-material-table. там я попытался добавить пользовательскую проверку ввода, я создал отдельную службу валидатора, там я вызвал пользовательскую функцию для проверки моего API на основе результата API, он выбрасывает ввод правильно или нет.

вот мой код, может кто-нибудь подсказать мне, что ошибка, которую я сделал,

import { Injectable } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { ValidatorService } from 'angular4-material-table';
import { AbstractControl } from '@angular/forms';
import { ApiCallService } from 'api.service';

    @Injectable()
    export class MatTableValidatorService implements ValidatorService {
        constructor( private api_call: ApiCallService) {  
        }
       getRowValidator(): FormGroup {
        return new FormGroup({
          'name': new FormControl(null, [Validators.required, this.nameValidator]),
          });
      }
        nameValidator(control: AbstractControl): { [key: string]: boolean } | null {
            this.api_call
            .api_function(parameter)
            .subscribe(data => {
              const arrayVal = data.response;
              if(arrayVal.length > 0)
              {
                return {'dnsCheck': true}
              }
              return null;
          });
            return null;
        }

    }

эта возвращает ошибку: невозможно прочитать свойство api_call, даже если я объявил его в конструкторе

и другим способом:

   public nameValidator = (control: AbstractControl) => {
         this.api_call
            .api_function(parameter)
            .subscribe(data => {
              const arrayVal = data.response;
              if(arrayVal.length > 0)
              {
                return {'dnsCheck': true}
              }
              return null;
          });
        };

this способ работает, но даже если вход действителен или нет, он всегда выдает ошибку. Я проверил вывод с консоли, кажется, получение из API отлично сделано. Может ли кто-нибудь помочь мне в чем моя ошибка. Заранее спасибо.

Пример стекаблица можно увидеть здесь.

Ответы [ 2 ]

1 голос
/ 26 февраля 2020

Я не уверен, является ли это причиной, однако вы не ожидаете результата вашего вызова API. Ваш код всегда возвращает null. Поэтому нам нужно дождаться результата вызова API:

async nameValidator(control: AbstractControl): { [key: string]: boolean } | null {  
    const result = await this.api_call.api_function(parameter);
    const arrayVal = result.response;

    if (arrayVal.length > 0)
          return {'dnsCheck': true}

    return null;
}

ОБНОВЛЕНИЕ:

Вы можете добавить пользовательский валидатор. Запрещенное имя - Mark, если вы пишете запрещенное имя, то ввод не сохранит это значение:

@Injectable()
export class PersonValidatorService implements ValidatorService {
  getRowValidator(): FormGroup {
    return new FormGroup({
      'name': new FormControl(null, [Validators.required, forbiddenNameValidator()])

      });
  }
}

export function forbiddenNameValidator(): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} | null => {    
    const forbidden =  'Mark';
    console.log(`forbidden name is `, forbidden);
    return (forbidden == control.value) ? {'forbiddenName': {value: control.value}} : null;
  };
}

Пример можно увидеть здесь.

0 голосов
/ 26 февраля 2020

Angular Пользовательские проверки содержат другую область действия, и поэтому первый пример, который вы создали, не сработал.

Второй пример сработал, поскольку вы использовали «функцию стрелки». Поскольку ваша пользовательская проверка - asyn c, вам нужно вернуть наблюдаемое. Взгляните на следующий

Первый вариант:

nameValidator = (control: AbstractControl): Observable<{ [key: string]: boolean } | null> => {
    return this.api_call
        .api_function(parameter)
        .pipe(
            map(
                data => {
                    const arrayVal = data.response;
                    return arrayVal && arrayVal.length > 0 ? { 'dnsCheck': true } : null
                }
            )
        );
}

Второй параметр:

this.nameValidator.bind (это), где происходит магия c

getRowValidator(): FormGroup {
    return new FormGroup({
        'name': new FormControl(null, {
            asyncValidators: [this.nameValidator.bind(this)],
            validators: [Validators.required],
        }),
    });
}

nameValidator(control: AbstractControl): Observable < { [key: string]: boolean } | null > {
    return this.api_call
        .api_function(parameter)
        .pipe(
            map(
                data => {
                    const arrayVal = data.response;
                    return arrayVal && arrayVal.length > 0 ? { 'dnsCheck': true } : null
                }
            )
        );
}
...