javascript - 如何在 Angular 8 中启动应用程序时加载首先完成的数据服务

标签 javascript angular typescript service

这是我的 Angular 应用程序。我的应用程序将从 API 获取数据(暂时在 JSON 文件中)并显示在许多其他同级组件中。因此,我决定创建一个 category.service.ts 来获取并存储数据。当我的应用程序启动时,我首先使用 APP_INITIALIZER 运行此服务。但有一个问题:该服务先运行,AppComponent 在服务获取数据完成之前运行。所以我的 View 没有数据。

如果我单击路由到该组件的按钮,一切都会完美运行。但是当我通过 url 路径或 F5(刷新页面)转到该组件时,没有显示任何内容

category.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
  providedIn: 'root'
})
export class CategoryService {
  DATA_CATEGORIES = 'assets/categories.json';
  private _categories = [];
  constructor(private http: HttpClient) {
  }
  get categories() {
    return this._categories;
  }
  Init(): Promise<any> {
    return new Promise<void>(resolve => {
      this.http.get(this.DATA_CATEGORIES).subscribe(data => {
        this._categories = Array.from(Object.keys(data), k => data[k]);
        console.log("load data...");

      });
      resolve();
    });
  }
}

app.module.ts

export function initializeCategoryService(catService: CategoryService) {
  return (): Promise<any> => {
    return catService.Init();
  }
}
@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    StoriesFilterPipe,
    ViewStoryComponent,
    ViewCatComponent,
    FrontEndComponent,
    SearchComponent,
    BackEndComponent,
    CrudStoryFormComponent,
    CrudStoryComponent,
    JwPaginationComponent,
    CrudCatComponent,
    CrudCatFormComponent,
    CrudCatSearchResultComponent,
    CatListComponent

  ],
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule,
    HttpClientModule,
  ],
  providers: [
    StoryService,
    CategoryService,
    {
      provide: APP_INITIALIZER, useFactory: initializeCategoryService, deps: [CategoryService], multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

最佳答案

我建议使用Observable

就像您的类别服务

import { Observable, Subject } from 'rxjs';
export class CategoryService {
    private loadDataSub = new Subject<any>();
    loadDataObservable$ = this.loadDataSub.asObservable();

    emitLoadDataSuccess() {
        this.loadDataSub.next();
    }

Init(): Promise<any> {
    return new Promise<void>(resolve => {
      this.http.get(this.DATA_CATEGORIES).subscribe(data => {
        this._categories = Array.from(Object.keys(data), k => data[k]);
        console.log("load data...");
        this.emitLoadDataSuccess(); // here we are emitting event
      });
      resolve();
    });
 }
}

在你的组件中

export class AppComponent implements OnInit {
    constructor(private categoryService: CategoryService) {
          this.categoryService.loadDataObservable$.subscribe(() => {
              // here you can get data, this will only trigger when data is loaded from API
          });
    }
}

关于javascript - 如何在 Angular 8 中启动应用程序时加载首先完成的数据服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60147154/

相关文章:

javascript - 从另一个文件中的类调用函数

Angular 5 - 在加载数据之前停止来自 undefined object 的错误

javascript - 将 $(this) 编译为 $(_this)

reactjs - Material UI Tab 将 props 传递给组件

javascript - 如何防止粘贴到输入的脚本注入(inject)

Javascript:for 循环没有按预期工作

javascript - 如何在 body onload 上播放音频?

typescript - gulp-typescript 在保存时发出错误,但在后续保存时没问题

twitter-bootstrap-3 - 如何在 Angular2 中实现可折叠侧边栏?

typescript :的意思?和 !在类属性中