Rxjs 角度2:获得服务';调用方法之前的属性值

Rxjs 角度2:获得服务';调用方法之前的属性值,rxjs,Rxjs,我已经在我的应用程序中将FireDatabaseService实现为@Injectable({providedIn:'root'})。它当然适用于DI。在这个服务中,我需要来自另一个服务的Firebase UID,但这个UID是通过订阅获取的。因此,需要UID的方法在该UID可用之前被调用。在调用getUserGroup()之前,我不知道如何获取UID。这是我的服务: ... @Injectable({ providedIn: 'root' }) export class FireDatabas

我已经在我的应用程序中将
FireDatabaseService
实现为
@Injectable({providedIn:'root'})
。它当然适用于DI。在这个服务中,我需要来自另一个服务的Firebase UID,但这个UID是通过订阅获取的。因此,需要UID的方法在该UID可用之前被调用。在调用
getUserGroup()
之前,我不知道如何获取UID。这是我的服务:

...
@Injectable({ providedIn: 'root' })
export class FireDatabaseService {
  uid: string;

  constructor(
    private readonly db: AngularFireDatabase,
    private readonly authService: AuthService
  ) {
    this.authService.authState.subscribe(
      (state: firebase.User) => this.uid = state.uid
    );
  }

  getUserGroup(): Observable<string> {
    return this.db
      .object(`users/${this.uid}`)
      .valueChanges()
      .pipe(map((userData: any) => userData?.group as string));
  ...
  }
。。。
@可注射({providedIn:'root'})
导出类FireDatabaseService{
uid:字符串;
建造师(
专用只读数据库:AngularFireDatabase,
私有只读authService:authService
) {
this.authService.authState.subscribe(
(state:firebase.User)=>this.uid=state.uid
);
}
getUserGroup():可观察{
返回这个.db
.object(`users/${this.uid}`)
.valueChanges()
.pipe(map((userData:any)=>userData?.group作为字符串));
...
}

调用
fireDatabaseService.getUserGroup()
需要
uid='
。有没有可能修复它?谢谢帮助。

我不太清楚您的要求是什么。要完成我认为您要求的任务,最简单的方法是:

...
@Injectable({ providedIn: 'root' })
export class FireDatabaseService {
  constructor(
    private readonly db: AngularFireDatabase,
    private readonly authService: AuthService
  ) {
  }

  getUserGroup(): Observable<string> {
    return this.authService
               .authState
               .pipe(
                   switchMap((state: firebase.User) => 
                       this.db
                           .object(`users/${state.uid}`)
                           .valueChanges()
                   ),
                   map((userData: any) => userData?.group as string)
               );
  ...
  }
。。。
@可注射({providedIn:'root'})
导出类FireDatabaseService{
建造师(
专用只读数据库:AngularFireDatabase,
私有只读authService:authService
) {
}
getUserGroup():可观察{
返回此.authService
authState先生
.烟斗(
switchMap((状态:firebase.User)=>
这个是.db
.object(`users/${state.uid}`)
.valueChanges()
),
映射((userData:any)=>userData?.group作为字符串)
);
...
}

每次调用
getUserGroup
时,都会有另一个对authService的调用。这可能是不需要的,但可以通过使用
shareReplay(1)来缓解
或通过另一种策略(取决于您期望的功能)。

我不太清楚您的要求是什么。实现我认为您要求的最简单的方法是:

...
@Injectable({ providedIn: 'root' })
export class FireDatabaseService {
  constructor(
    private readonly db: AngularFireDatabase,
    private readonly authService: AuthService
  ) {
  }

  getUserGroup(): Observable<string> {
    return this.authService
               .authState
               .pipe(
                   switchMap((state: firebase.User) => 
                       this.db
                           .object(`users/${state.uid}`)
                           .valueChanges()
                   ),
                   map((userData: any) => userData?.group as string)
               );
  ...
  }
。。。
@可注射({providedIn:'root'})
导出类FireDatabaseService{
建造师(
专用只读数据库:AngularFireDatabase,
私有只读authService:authService
) {
}
getUserGroup():可观察{
返回此.authService
authState先生
.烟斗(
switchMap((状态:firebase.User)=>
这个是.db
.object(`users/${state.uid}`)
.valueChanges()
),
映射((userData:any)=>userData?.group作为字符串)
);
...
}

每次调用
getUserGroup
时,都会有另一个对authService的调用。这可能是不需要的,但可以通过使用
shareReplay(1)来缓解
或通过另一种策略,具体取决于您期望的功能。

我建议您不要在服务中订阅,而是将您的
uid
userGroup
定义为可观察对象。
userGroup$
可以从
uid$
可观察对象中定义:

@Injectable({providedIn:'root'})
导出类FireDatabaseService{
uid$=this.authService.authState.pipe(
映射(state=>state.uid)
);
用户组$=此.uid$.pipe(
switchMap(uid=>this.db.object(`users/${uid}`)).valueChanges()
映射(userData=>userData?.group作为字符串)
);
建造师(
专用只读数据库:AngularFireDatabase,
私有只读authService:authService
) { }
}

可观察对象是惰性的,因此不必将其包装为函数。它们在
.subscribe()之前不会发出值
被调用。

我建议您不要在服务中订阅,而是将您的
uid
userGroup
定义为可观察对象。
userGroup$
可以从
uid$
可观察对象中定义:

@Injectable({providedIn:'root'})
导出类FireDatabaseService{
uid$=this.authService.authState.pipe(
映射(state=>state.uid)
);
用户组$=此.uid$.pipe(
switchMap(uid=>this.db.object(`users/${uid}`)).valueChanges()
映射(userData=>userData?.group作为字符串)
);
建造师(
专用只读数据库:AngularFireDatabase,
私有只读authService:authService
) { }
}

可观察对象是惰性的,因此无需将其包装为函数。在对其调用
.subscribe()
之前,它们不会发出值。

userGroup$仍然需要定义的uid$,而uid$是在userGroup$调用之后定义的:(在上面的代码中,调用实际上不是在进行,它们只是在定义。因此,当调用
userGroup$.subscribe()
时,将首先进行
uid$
订阅,因此
userGroup$
内部的
switchMap
将获得当前的
uid
。请尝试:-)好吧,我给了,我只是重复一下我的控制台上说的:D:-)-你看到的确切错误是什么?第二个解决方案很有帮助,我认为已经足够了。但无论如何,谢谢!userGroup$仍然需要定义uid$,而uid$是在userGroup$调用之后定义的:(在上面的代码中,调用实际上并没有被调用,它们只是被定义。所以,当
userGroup$.subscribe()
被调用,将首先进行
uid$
订阅,因此
userGroup$
中的
switchMap
将获得当前的
uid
。尝试一下:-)好吧,我只是重复我的控制台所说的:D:-)-您看到的确切错误是什么?第二个解决方案很有帮助,我认为已经足够了。但无论如何,谢谢!好吧,它很有效。目前:)非常感谢