Angular 7-使用BehaviorSubject将API结果发布到所有组件

问题描述 投票:0回答:1

我有一个API调用,该调用返回有关当前用户的数据(即用户名,全名,授权组成员身份,电子邮件地址等)。我只想在每个用户会话中调用一次此API,并在所有组件之间共享其数据。

我不想依赖localStorage,因为我不希望用户修改此数据。我正在尝试使用BehaviorSubject并尝试了以下示例,但是在尝试通过组件访问它时,我一直收到初始值(null)。

// HTTP Service:
getUserData() {
  const url = `${baseUrl}/api/users/`;
  return this.httpClient.get<UserData>(url).toPromise();
}
// Utils Service
export class UtilsService {
  private userDataSubject: BehaviorSubject<UserData>;

  constructor(
    private httpService: HttpService,
  ) {
    this.userDataSubject = new BehaviorSubject<UserData>(null);
    this.setUserData();
  }

  async setUserData() {
    let userData: UserData = await this.httpService.getUserData();
    this.userDataSubject.next(userData);
    console.log(this.userDataSubject.value); // Properly returns the data I want     
  }

  public get userDataValue(): UserData {
    return this.userDataSubject.value;
  }
// Component
  ngOnInit() {
    this.userData = this.utils.userDataValue; // This is the variable I need to set in my component.
    console.log(this.userData);               // Returns null
    console.log(this.utils.userDataValue);    // Also returns null
  }

我也尝试过为userDataValue()使用异步函数:

async userDataValue(): Promise<UserData> {
    return this.userDataSubject.value;
  }

并修改了我的组件:

async ngOnInit() {
    this.userData = await this.utils.userDataValue();
    console.log(this.userData);                    // Still returns null
    console.log(await this.utils.userDataValue()); // Still returns null
  }

到目前为止,只有避免使用BehaviorSubject并在每个组件中调用API的情况下,我才能使这项工作正常进行,但这似乎没有必要。非常感谢您提供有关如何进行此工作的指导。谢谢。

angular global-variables behaviorsubject
1个回答
0
投票

问题是setUserData()是一个异步函数,this.httpService.getUserData()需要一些时间才能从后端获取数据。因此,当您的组件调用它ngOnInit()时,方法userDataSubject尚未收到新值,这就是它返回null的原因。我建议使用BehaviorSubject subscribe处理程序,以便您的代码在正确的时间执行应做的事情。就像这样:

export class UtilsService {
  public userDataSubject: BehaviorSubject<UserData>;

  constructor(private httpService: HttpService) {
    this.userDataSubject = new BehaviorSubject<UserData>(null);
    this.setUserData();
  }

  async setUserData() {
    let userData: UserData = await this.httpService.getUserData();
    this.userDataSubject.next(userData);     
  }

以及您的组件中

ngOnInit() {
  this.utils.userDataSubject.subscribe((data) => {
    console.log(data);

     // component logic to use your data
     // this will be called every time userDataSubject receives a new value
  });
}
© www.soinside.com 2019 - 2024. All rights reserved.