Доступ к сервису из настраиваемого валидатора в Angular2

Мне нужно получить доступ к моей настраиваемой службе http из статического метода, например:

import {Control} from 'angular2/common';
import {HttpService} from './http.service';

class UsernameValidator {
    static usernameExist(control: Control): Promise<ValidationResult> { 
        ... /* Access my HTTPservice here */
    }
}

Как я могу получить доступ к услуге в этом случае?


person Silencer    schedule 19.02.2016    source источник
comment
Не могли бы вы добавить еще фрагмент кода?   -  person micronyks    schedule 19.02.2016
comment
Что такое HTTPService? Выложите его фрагмент.   -  person micronyks    schedule 19.02.2016


Ответы (3)


Другой подход заключается в возврате функции. Таким образом, эта функция может иметь доступ к экземпляру HttpService, предоставленному во время создания:

class UsernameValidator {
  static createUsernameExist(http:HttpService) {
    return (control: Control) => { 
      ... /* Access my HTTPservice here */
    }
  }
}

Затем вы можете использовать это так:

validator: UsernameValidator.createUsernameExist(this.httpService)
person Thierry Templier    schedule 19.02.2016
comment
При инициализации FormControl следующим образом: username: ['', [Validators.required, UsernameValidator.createUsernameExist(this.httpService)]] Я получаю сообщение об ошибке TypeError: UsernameValidator.createUsernameExist не является функцией, как это сделать? - person mdziob; 04.10.2016
comment
Я следую этому примеру, и я могу видеть вывод журнала для каждого случая, но мое поле никогда не является действительным. Как должен выглядеть сервисный вызов? Это то, что я использую. return (control: Control) = ›{... / * Доступ к моему HTTP-сервису здесь * / return myService.getStuff (). subscribe (data =› {if (bad) {return {bad: true}} else {return null; }}} - person Adam Mendoza; 07.04.2017

class UsernameValidator {
    constructor(http:HttpService){}

    usernameExist(control: Control): Promise<ValidationResult> { 
        ... /* Access my HTTPservice here */
    }
}

тогда используйте это как

validator: new UsernameValidator(http).usernameExist

Вместо этого HttpService необходимо ввести в конструктор компонента, а затем передать в созданный вручную экземпляр валидатора, как показано выше.

person Günter Zöchbauer    schedule 19.02.2016
comment
Итак, мне нужно создавать новые объекты для каждого асинхронного валидатора? Было бы неплохо реализовать мой валидатор как встроенный Validators.minLength(12) и передать http в качестве параметра? - person Silencer; 19.02.2016
comment
Конечно, если вы используете его как директиву, то HttpService можно ввести напрямую. Я взял на себя FormBuilder. - person Günter Zöchbauer; 19.02.2016
comment
Спасибо за ваш ответ, после этого я реализовал то же самое, что дал Тьерри, поэтому я принял его ответ. - person Silencer; 19.02.2016
comment
это все еще путь? Я бы надеялся, что валидаторы можно будет инсталлировать и автоматически вводить зависимости (я не хочу называть `` новые '') - person Tobias Gassmann; 09.08.2017
comment
В новом нет ничего плохого, но вы также можете сделать его сервисом и внедрить его. Какой путь выбрать - решать вам. - person Günter Zöchbauer; 09.08.2017

Используя ответ Гюнтера Цохбауэра, я реализовал свой валидатор для доступа к службам из AsyncValidatorFn ...

IMHO кажется более чистым, позволяя DI вводить зависимости службы непосредственно в класс валидатора вместо передачи зависимостей статическому методу из потребительского компонента для создания AsyncValidatorFn.

Создайте свой инъекционный класс валидатора

import { Injectable } from '@angular/core';
import { AbstractControl, AsyncValidatorFn, ValidationErrors } from '@angular/forms';

@Injectable
export class UsernameValidator {
  constructor(
    private http: HttpService,
  ) { }

  usernameExists: AsyncValidatorFn = (control: AbstractControl): Observable<ValidationErrors> => {
    // access your HttpService here...
  }
}

Предоставьте валидатор для внедрения в объявлении вашего модуля

@NgModule({
  providers: [
    UsernameValidator, // register your validator for injection
  ],
})
export class UserModule { }

Установите функцию валидатора в форме компонента

constructor(
  private formBuilder: FormBuilder,
  private usernameValidator: UsernameValidator, // inject your validator
) { }

ngOnInit() {
  this.form = this.formBuilder.group({
    username: [
      null, // initial value
      [Validators.required], // sync validators
      [this.usernameValidator.usernameExists], // async validators
    ],
  });
}
person j3ff    schedule 12.10.2018