Javascript 等待LoginService中加载的用户数据
我想在我的LoginService中加载我的用户数据节点,并在加载其他服务之前等待,因为所有其他服务的路径的一部分取决于userdata。(在我的例子中,我想在userdata节点中保存一个gameid->例如,我的用户有一个指定的gameid:1 其他数据的路径为/1/chat,…) Auth.guard.tsJavascript 等待LoginService中加载的用户数据,javascript,angular,firebase,firebase-realtime-database,angularfire2,Javascript,Angular,Firebase,Firebase Realtime Database,Angularfire2,我想在我的LoginService中加载我的用户数据节点,并在加载其他服务之前等待,因为所有其他服务的路径的一部分取决于userdata。(在我的例子中,我想在userdata节点中保存一个gameid->例如,我的用户有一个指定的gameid:1 其他数据的路径为/1/chat,…) Auth.guard.ts //Angular import { Observable } from 'rxjs/Rx'; import { Injectable } from '@angular/core';
//Angular
import { Observable } from 'rxjs/Rx';
import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
//Services
import { LoginService } from '../services/login.service';
@Injectable()
export class AuthGuard implements CanActivate{
constructor(
private router: Router,
private loginService: LoginService,
){}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return this.loginService.getAuthenticated().map(user => {
this.loginService.setUser(user);
if(user) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
})
}
}
Chat.service.ts常用的方法是在
LoginService
中提供一个可观察的,所有其他服务都可以订阅,并且LoginService
使用该服务将状态更改通知其他感兴趣的服务和组件
@Injectable()
export class LoginService {
private loginData:Subject = new BehaviorSubject();
public loginData$ = this.loginData.asObservable();
setUser(user): void {
this.user = user;
//update last activity
if(this.user != undefined && this.user != null){
this.af.database.object(`users/${this.user.uid}`).subscribe(user => { this.gameid = user.gameid;
this.loginData.next(...); }
}
}
@guenter谢谢你的回答,我已经以类似的方式尝试过了,但是我的问题是聊天的getLast方法在构造函数中的observable完成之前就被处理了。在控制台中,这看起来像这样:Line1 getLast。ID.未索引的Line2 Angular正在开发模式下运行。调用enableProdMode()以启用生产模式。第3行构造函数。ID.1在哪里调用getLast()
?调用我编写的this.init()
的getLast()
怎么样?getLast()在我的app.component.ts中被调用,但这只是我应用中使用的全部服务之一。。我还有一个dashboard.component.ts,它由app.component.ts路由,在这里我有很多其他服务调用,这些调用都是在组件的ngInit()上调用的。这听起来不像是一个通用的答案。我假设您需要为forkJoin
使用可观察的操作符,如merge
,将异步调用链接在一起。事实上,这不是我的专业领域,因为我没有使用TS(仅Dart),但是有很多关于如何等待其他观察完成的问题和答案。我认为没有太多的观察合并或其他东西。。最简单的方法可能是在使用ngInit()的组件中触发的我的服务方法中订阅loginService.loginda
//Angular
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs';
//Firebase
import { FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2';
//Services
import { LoginService } from '../services/login.service';
import { MembersService } from '../services/members.service';
//Models
import { ChatModel } from '../models/chat';
@Injectable()
export class ChatService {
constructor (
private loginService: LoginService,
private membersService: MembersService,
private router: Router
){}
getLast(): Observable<any> {
return this.loginService.af.database.list(this.loginService.gameid+`/chat/`)
}
}
@Injectable()
export class LoginService {
private loginData:Subject = new BehaviorSubject();
public loginData$ = this.loginData.asObservable();
setUser(user): void {
this.user = user;
//update last activity
if(this.user != undefined && this.user != null){
this.af.database.object(`users/${this.user.uid}`).subscribe(user => { this.gameid = user.gameid;
this.loginData.next(...); }
}
}
@Injectable()
export class ChatService {
constructor (
private loginService: LoginService,
private membersService: MembersService,
private router: Router
){
loginService.loginData.filter(ld => ld != null).subscribe(res =>
this.loginData = res;
this.init(); // do additional initalization
});
}