如何将服务注入异步验证器?

时间:2017-09-14 14:13:15

标签: angular

我有两个非常相似的异步验证器。两者都检查唯一性值:电子邮件和首字母。第一个看起来像这样:

public static createEmailUniqueValidator(userService: UserService, originalEmailAddressFn: () => string) {
    return (control: AbstractControl): Observable<ValidationErrors> => {
        const originalEmailAddress: string = originalEmailAddressFn();
        if (originalEmailAddress && originalEmailAddress === control.value) {
            return Observable.of({});
        }
        return Observable.timer(1000).switchMap(() => {
            return userService
                .isEmailAddressUnique(control.value)
                .map(result => (result ? null : { 'This email address is already in use': true }));
        });
    }
}

第二个几乎相同,除了它在userService上调用的方法。 如何创建一个通用验证器工厂并将其调用的方法传递给实际检查?

到目前为止,我有这个:

public static createValidator(uniqueFn: (value: string) => Observable<Boolean>, originalEmailAddressFn: () => string, errorMessage: string) {
        return (control: AbstractControl): Observable<ValidationErrors> => {
            const originalEmailAddress: string = originalEmailAddressFn();
            if (originalEmailAddress && originalEmailAddress === control.value) {
                return Observable.of({});
            }
            return Observable.timer(1000).switchMap(() => {
                return uniqueFn(control.value)
                    .map(result => (result ? null : { errorMessage: true }));
            });
        }
    }

但是我收到以下错误:

  

错误TypeError:无法读取未定义的属性'restService'       在webpackJsonp ... / .. / .. / .. / .. / src / app / services / user / user.service.ts.UserService.isEmailAddressUnique   (user.service.ts:108)

restService是另一个在userService中注入的服务。 看起来依赖关系尚未解决。我该如何解决这个问题?

这是我的userService:

// imports ...

@Injectable()
export class UserService {

  // [...]

  constructor(private restService: RestService) { }

  isEmailAddressUnique(emailAddress: string): Observable<Boolean> {
    return this.restService.get(this.usersUrl + '/validateUniqueEmailAddress/' + emailAddress);
  }
}

1 个答案:

答案 0 :(得分:4)

修改 两者都误解了所需的功能数量,并没有完全解释。花时间创建一个与您的设置大致匹配的(略微简化的)plunker(而不是尝试检查API,它只检查电子邮件是否有效,但是作为Observable执行;它还删除了{{{{{{ 1}}专注于基本工厂。)

我创建了working versionnon-working version。后者成功地再现了您在运行时看到的错误(createValidator)。有关重大变化,请参阅Cannot read property 'restService' of undefined。我在下面进行了更新,以突出显示使用胖箭头声明来正确绑定src/user.service.ts的两个函数。如果有什么我在插件中过度简化了,请告诉我,我们可以一起工作。

使用胖箭头声明的重要功能:

this

public static = createValidator(/*same parameters*/) => {
    // same content
}