Я столкнулся с аналогичной ситуацией, используя Angular v5.2.9 с проверкой того, что имя пользователя еще не существует в моей базе данных. Мой вариант использования немного отличается. Я использую небольшой список пользователей, который легко кэшируется, а мои данные централизованы с помощью библиотеки @ngrx, но я надеюсь, что это может быть полезно.
Начиная с класса Validator, конструктор отвечает за создание запроса на выборку и кэширование результатов в статическом списке, который можно наблюдать; этот наблюдаемый список будет использоваться фактическим методом проверки, чтобы увидеть, используется ли уже имя пользователя.
import { Injectable } from '@angular/core'
import { FormControl } from '@angular/forms'
import { Store } from '@ngrx/store'
import { Observable } from 'rxjs/observable'
import 'rxjs/add/operator/take'
import 'rxjs/add/operator/map'
import { myActions } from '../@ngrx/actions/some.actions'
import { State, selectIds } from '../@ngrx/reducers/some.reducer'
@Injectable()
export class CustomValidators {
static ids_in_use$: Observable<string[]>;
constructor(
private store: Store<State>
) {
this.store.dispatch({ type: myActions.FETCH_REQUEST })
CustomValidators.ids_in_use$ = this.store
.select( selectIds )
.map( ( id_list: string[] ) => id_list.map( id => id.toLowerCase() ) )
}
static api( control: FormControl ) {
return new Promise(
( resolve ) => {
CustomValidators.ids_in_use$
.take( 1 )
.subscribe(
id_list => {
if( id_list.indexOf( control.value.toLowerCase() ) === -1 )
resolve( null )
else resolve({ 'email-in-use': true })
})
})
}
Чтобы обойти отсутствие доступа к свойствам экземпляра в статических методах, за установку статических свойств отвечает конструктор валидатора. Поскольку этот класс украшен @Injectable()
, его можно внедрить с помощью зависимости в конструктор компонента, который его использует:
constructor(
...,
private fb: FormBuilder,
private customValidators: CustomValidators
) { }
Вот как я могу убедиться, что код в конструкторе валидатора выполняется, несмотря на то, что основная логика проверки является статическим методом. Точно так же я полагаю, что вы могли бы использовать этот экземпляр, чтобы использовать любые свойства/методы экземпляра, которые вам особенно нужны, до проверки в вашем случае, делая http-запрос. Затем я могу использовать метод статической проверки в группе FormBuilder (имейте в виду, что если вы не вызовете его, ваш tslint предупредит вас об этом 'customValidators' is declared but its value is never read
)
this._formDetails = fb.group({
'managerEmail': [ '', Validators.required, CustomValidators.api ]
})
Наконец, для внедряемой службы необходимо объявить провайдера, что можно сделать в декораторе @Component
:
@Component({
...,
providers: [ CustomValidators ]
})
person
Cole Cooper
schedule
22.03.2018