首页 > 解决方案 > Angular 6 - 使用范围外的函数和回调函数

问题描述

我正在使用 DevExtreme 组件,这是在 html 中调用回调函数的地方:

<dxi-validation-rule type="custom"
     [validationCallback]="validationCallback"
     message="Email exists">
</dxi-validation-rule>

在 ts 文件中:

validationCallback (e)  {
  const x = this.userService.getUserByEmail(e.value);
  x.subscribe(ref => ref.email != null ? true : false);
  return x;
}

服务代码:

getUserByEmail(email: string): Observable<User> {
  return this.afs
    .collection<User>('users', ref => ref.where('email', '==', email))
    .snapshotChanges()
    .map(
      users => {
        const user = users[0];
        if (user) {
          const data = user.payload.doc.data() as User;
          const id = user.payload.doc.id;
          console.log('found: ' + data.email);
          return { id, ...data };
        } else {
          return null;
        }
      }
    );
}

该代码的问题是我得到:

Cannot read property 'getUserByEmail' of undefined

基本上意味着我正在尝试访问this.userService超出函数范围的内容。在这种情况下,我如何能够访问外部函数来验证电子邮件?

标签: angularrxjsangular2-services

解决方案


may be a one way to do it by create a method that return an arrow function then set getUserByEmail to that arrow function this way you will obtain a reference to this object

public getUserByEmail;

ngOnInit() {
 this.getUserByEmail = getUserByEmailFactory();
}

getUserByEmailFactory() {

  return  (email: string) => {
    return this.afs
      .collection<User>('users', ref => ref.where('email', '==', email))
      .snapshotChanges()
      .map(
        users => {
          const user = users[0];
          if (user) {
            const data = user.payload.doc.data() as User;
            const id = user.payload.doc.id;
            console.log('found: ' + data.email);
            return { id, ...data };
          } else {
            return null;
          }
        }
      );
  }

}

you can an afs to getUserByEmailFactory then the return function will have a closure then you will no longer need to use this

public getUserByEmailFactory(afs){
 ...
}

ngOnInit() {
  this.getUserByEmail = getUserByEmailFactory(this.afs);
}

or can be like this

public getUserByEmail = () => { ... }

arrow function


推荐阅读