在数据加载之前,我的 Angular 订阅函数是 运行。有没有什么办法解决这一问题?

My Angular subscribe function is running before the data has loaded. Is there any way to fix this?

我在订阅 运行ning 获取数据之前遇到问题。我有 3 个组件需要加载 3 个数据。因此,我没有调用后端 3 次,而是将它们全部放入从后端加载的一个数组中,然后在加载时划分为 3 个组件。一些组件需要相同的数据。

所以我有一个从后端获取代码的服务。当我的函数取回数据时,我用名为 setFolderStore 的数据加载了一个 setter 函数,并且我有一个 getFolderStore 函数调用。问题是在我设置数据之前,我的组件似乎 运行 正在访问 getFolderStore。我这样做是为了让我的其他组件可以获取数据,而无需重新运行 调用后端。

//Service
private folderStore = new BehaviorSubject<adminInterfaces.IfolderList[]>([]);

buildGallery(postData: any): Observable<any> {
   return this.httpClient.post(this.apiUrl +'commander/readImagesFolders', postData).pipe(
      map((postData:any)=>{
         this.setFolderStore(postData.folderList);// this sets one part of my data.
         return postData;
      })
   );
}
public setFolderStore(store:any) {
    this.folderStore.next(store);
}
public getFolderStore(): Observable<Array<adminInterfaces.IfolderList>>{
    return this.folderStore.asObservable();
}

在我的第一个组件中,我 运行 buildGallery。

// First component  
this.adminService.buildGallery(this.postData).subscribe(res => {
         this.image = <gallery.IgalleryData>res.organise;
      error => {
      });
}

在我的第二个组件中,我有一个控制台日志。它 运行s 曾经是空的,然后 运行s 又是完整的数据,但到那时我已经得到了一个错误,因为我正在从数据中设置一个索引,这显然失败了。当然它应该等待 this.folderStore.next(store) 成为 运行?

ngOnInit(): void {
   this.getFolderStoreSubscribe = this.adminService.getFolderStore().subscribe((data) => {
      let index = 0;
      if(typeof data !== null){
         console.log(data);
         if (this._route.snapshot.queryParamMap.has('f')) {
            this.currentFolderID = this._route.snapshot.queryParamMap.get('f');
            index = data.findIndex(x => x.folder_id == this.currentFolderID);
            this.folderName = data[index].name;// Here this is generating an error because the subscribe is running before I get the data.
         }
      }
   });
}

那么,为什么我的订阅 运行 在获取数据之前就处于 ning 状态,是否有解决该问题的方法?真的,在我调用 setFolderStore 之前,订阅不应该 运行。

请根据主题更改行为,这样您将不会获得任何初始值。

private folderStore = new Subject<adminInterfaces.IfolderList[]>();

BehaviourSubject(一种主题)用于设置主题的初始值并希望获得one该主题发出的先前值你的订阅块。因此,无论何时您订阅它,它都会发出当前值,该值在您设置为空状态的那一刻。我认为有两种解决方案:

第一个(推荐) 由于您不需要初始值,因此应该使用 Subject 而不是 BehaviorSubject。所以你的初始化看起来像这样:

//Service
private folderStore = new Subject<adminInterfaces.IfolderList[]>();

第二种方法(出于某种原因你想使用BehaviorSubject) 您可以在尝试访问值之前检查 data[index] 是否为 null,即

 if(data[index]) { 
    this.folderName = data[index].name; 
  }

但我建议您使用第一种方法。

还有一个小比较,可以帮助我选择要创建的 Subject 类型。