Angular 角度2+;:带有反应式表单的自定义异步验证器

Angular 角度2+;:带有反应式表单的自定义异步验证器,angular,customvalidator,reactive-forms,Angular,Customvalidator,Reactive Forms,我正在尝试从模板驱动切换到反应式表单。当异步验证器以模板驱动的形式在输入元素中使用set属性时,我正在添加异步验证器,现在当尝试从代码中设置时,经常会出现一个奇怪的错误“TypeError:undefined不是对象(计算'this.http')”: 验证器使用类成员,但由于您将其作为引用传递-,因此未正确定义此 尝试: @Component({ selector: 'app-new-user', templateUrl: './new-user.component.html',

我正在尝试从模板驱动切换到反应式表单。当异步验证器以模板驱动的形式在输入元素中使用set属性时,我正在添加异步验证器,现在当尝试从代码中设置时,经常会出现一个奇怪的错误“TypeError:undefined不是对象(计算'this.http')”:


验证器使用类成员,但由于您将其作为引用传递-
,因此未正确定义此

尝试:

@Component({
    selector: 'app-new-user',
    templateUrl: './new-user.component.html',
    styleUrls: ['./new-user.component.css']
})
export class NewUserComponent implements OnInit, OnDestroy {
    isPosting: boolean = false;
    storeSub: Subscription;

    newUserForm: FormGroup;

    constructor(
        private userService: UsersService,
        private http: HttpClient,
        private store: Store<fromApp.AppState>
    ) {

    }

    ngOnInit() {
        this.storeSub = this.store.select('users')
            .subscribe(state => {
                    this.isPosting = state.isPostingNewUser;
                }
            );
        this.newUserForm = new FormGroup({
            'name': new FormControl(null, [
                Validators.required,
                Validators.maxLength(30),
                Validators.minLength(3)
            ]),
            'surname': new FormControl(null, [
                Validators.required,
                Validators.maxLength(50),
                Validators.minLength(3)
            ]),
            'email': new FormControl(null, [
                    Validators.required,
                    Validators.email
                ],
                this.checkEmailAvailability
            ),
            'phone': new FormControl(null, [
                    Validators.required,
                    Validators.maxLength(9),
                    Validators.pattern('[5-8][0-9]{8}')
                ]
            )
        });

    }

    ngOnDestroy() {
        this.storeSub.unsubscribe();
    }

    onSubmit(): void {
        const userWriteModel = new UserWriteModel(
            this.newUserForm.get('name').value,
            this.newUserForm.get('surname').value,
            this.newUserForm.get('email').value,
            this.newUserForm.get('phone').value
        );
        this.store.dispatch(new UserActions.AddUser(userWriteModel));
    }

    checkEmailAvailability(control: FormControl): Observable<{ emailForbidden: boolean } | null> {
        const emailToCheck = control.value;
        if(!emailToCheck) {
            return of(null);
        }
        const queryParams = new HttpParams().set('email', emailToCheck);
        console.log(emailToCheck);
        return of(emailToCheck).pipe(
            debounceTime(400),
            switchMap(emailToCheck => {
                return this.http.get<{ email: string, available: boolean }>(ENDPOINT + '/email/available', {params: queryParams})
                    .pipe(
                        map(resp => {
                            if (resp.email === emailToCheck && resp.available === false) {
                                return {emailForbidden: !resp.available};
                            }
                            return null;
                        }), catchError(() => of(null)));
            })
        );
    }
}
[Error] ERROR
TypeError: undefined is not an object (evaluating 'this.http')
(anonimowa funkcja) — new-user.component.ts:106
_next — switchMap.js:30
next — Subscriber.js:49
debouncedNext — debounceTime.js:40
_complete — debounceTime.js:31
complete — Subscriber.js:61
(anonimowa funkcja) — subscribeToArray.js:5
_trySubscribe — Observable.js:42
subscribe — Observable.js:28
subscribe — Observable.js:23
subscribe — Observable.js:23
(anonimowa funkcja) — forkJoin.js:37
_trySubscribe — Observable.js:42
subscribe — Observable.js:28
subscribe — Observable.js:23
_runAsyncValidator — forms.js:3032
updateValueAndValidity — forms.js:3005
setValue — forms.js:3386
updateControl — forms.js:2407
(anonimowa funkcja) — forms.js:2392
_handleInput — forms.js:242
executeListenerWithErrorHandling — core.js:14296
wrapListenerIn_markDirtyAndPreventDefault — core.js:14331
(anonimowa funkcja) — platform-browser.js:582
onInvokeTask — core.js:27137
runTask — zone-evergreen.js:167
invokeTask — zone-evergreen.js:480
invokeTask — zone-evergreen.js:1621
globalZoneAwareCallback — zone-evergreen.js:1647
dispatchEvent
_autoFillControlWithValueAndOptions
_autoFillControlWithValue
(anonimowa funkcja)
[native code]
    defaultErrorLogger (vendor.js:18351)
    handleError (vendor.js:18399)
    next (vendor.js:41970)
    (anonimowa funkcja) (vendor.js:38808)
    __tryOrUnsub (vendor.js:70827)
    next (vendor.js:70766)
    _next (vendor.js:70716)
    next (vendor.js:70693)
    next (vendor.js:70479)
    emit (vendor.js:38798)
    run (polyfills.js:136)
    onHandleError (vendor.js:41442)
    runTask (polyfills.js:183)
    invokeTask (polyfills.js:493)
    timer (polyfills.js:2565)```
'email': new FormControl(null, [
                    Validators.required,
                    Validators.email
                ],
                this.checkEmailAvailability.bind(this)
            ),