【问题标题】:Angular HTTP sync request in Life Cycle event生命周期事件中的角度 HTTP 同步请求
【发布时间】:2020-05-06 02:59:28
【问题描述】:

在 Angular2+ 中,如何确保 HTTP 请求(或 Observable)在进入下一行之前完成。 https://stackblitz.com/edit/angular-uvtfln

export class AppComponent implements OnInit, AfterViewInit  {
  name = 'AngularX';
  systemPreference: any;

  constructor(private http: HttpClient){
  }

  ngOnInit(){
    console.log("ngOnInit");
    //get system preference, it is used in whole app,
    //it needs to be available so other component can use it.
    this.http.get("https://data.hawaii.gov/api/views/usep-nua7/rows.json").subscribe(res=>{
      //How to make it is done before go to the next life circle event?
      this.systemPreference = res;
    })
  }

  ngAfterViewInit(){
    console.log("ngAfterViewInit");
    //the below got undefined, I expect the subscriber must be done at ngOnInit 
    //before reaching this function (ngAfterViewInit)
    console.log(this.systemPreference);
  }
}

【问题讨论】:

  • 由于您没有从该方法返回任何内容,因此它无法等待,但无论如何,angular 无论如何都不支持这一点。你需要调整你的代码。为什么你需要在一个钩子中执行部分逻辑而在另一个钩子中执行部分逻辑?有一些框架,比如 Aurelia,支持异步生命周期钩子,但 Angular 不是其中之一。但是,即使是这样,这也不是该支持的好用例。请解释为什么要在不同的生命周期钩子中执行部分逻辑
  • 想象它是系统信息并且在整个应用程序中使用,它需要可用,以便其他组件可以使用它。
  • 这与生命周期挂钩没有任何关系

标签: angular rxjs observable angular-httpclient rxjs6


【解决方案1】:

我唯一能想到的就是使用 BehaviorSubject 或仅使用 Subject。考虑进行以下更改:

systemPreference = new BehaviorSubject<any>({});

  ngOnInit(){
    console.log("ngOnInit");
    //get system preference
    this.http.get("https://data.hawaii.gov/api/views/usep-nua7/rows.json").subscribe(res=>{
      systemPreference.next(res);
    })


  ngAfterViewInit(){
    console.log("ngAfterViewInit");
  systemPreference.subscribe(pref => 
    console.log(pref ));
  }

我认为这个修复是一种 hack,正确的方法是被动地处理这个问题。如果没有大局,很难为您提供有关反应式方法的指导。

-艾萨克

【讨论】:

  • 感谢艾萨克的快速回复。我需要可用的数据,以便其他组件可以使用它。成像 systemPreference 被整个应用程序使用,而不仅仅是 AppComponent 的 ngAfterViewInit。因此,它必须在其他组件启动之前准备好。
  • 再看看我的 Stack Blitz,stackblitz.com/edit/angular-krno5t。我举了一个例子,说明子组件如何仅在可用时使用该数据。 stackblitz.com/edit/angular-krno5t 在最新版本中,应用程序只有在加载了首选项后才会加载子组件。
  • 你太热心了,艾萨克。非常感谢。因为 systemPreference 不只是直接子组件使用,我希望把它放到一个服务中,所以任何组件/拦截器/...都可以使用它。但是正如我们所看到的,因为 http 是异步请求,所以有一种情况是组件在没有 systemPreference 的情况下进行初始化。您可以想象我需要整个应用程序的解析器,而不仅仅是组件。在 Angular 初始化任何其他组件之前必须做一些事情。
  • 至于其他组件在数据可用之前被初始化,这就是 *ngIf 的目的。它只会在条件为真时初始化组件;相反,当条件再次为假时,它将调用 ngOnDestroy 并处置您的组件。就共享数据而言,您需要创建一个服务来管理您的状态。
猜你喜欢
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
  • 2019-08-13
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多