簡體   English   中英

在ngoninit啟動之前等待http獲取請求完成angular

[英]Wait for http get request is finished before ngoninit starts angular

概括

我在 Angular 上有一個應用程序。 , (tabs.component.ts) and (io.component.ts).我有三個組件: 、child1 ( ) 和 child2 ( )。 另外,我有一個服務可以向 tomcat 服務器發送 get 和 post 請求。

i have a ngoninit, where i invoke service method get.在 child1 中,我有一個 ,我在其中調用服務方法 get。 .我在 child2 也有 starts first. child1 的首先啟動。 get request fetch data from server too slow and ngoninit from starts before get.subscribe(data=>this.data=data) .在 child1 中,從服務器獲取數據的速度太慢,而 child2 的 get.subscribe(data=>this.data=data)之前開始。

uses this data and as get request not returned data yet it fills with undefined .所以問題是來自 child2 的方法使用了這個data ,並且作為 get 請求沒有返回數據但它填充了undefined 所以,我有下一個序列:

序列(控制台)

試過了

in all cases loaded before get finished.使用asyncawaittoPromise()但它不起作用,來自 child2 的在所有情況下都在完成之前加載。

一些代碼

來自 child1 的 ngOnInit

subsystems: Subsystem[]; //need to ngFor them on html
currentTabId;

constructor(private terminalService: TerminalService) {}

ngOnInit() {
try {
  console.log('child1 ngoninit');
  this.terminalService.getSubsystems().subscribe((data: []) => {
    console.log('get in child1 finished');
    this.subsystems=data;
    this.currentTabId=0;
    this.terminalService.setSubsystem(this.subsystems[this.currentTabId]);
  });
} catch (exception) {
  console.log(exception);
}
}

來自 child2 的 ngOnInit

這里我有一個錯誤: TypeError: Cannot read property 'name' of undefined

constructor(private terminalService: TerminalService) {}

ngOnInit() {
try {
  console.log('child2 ngoninit');
  this.terminalService
    .getResultsBySubsystem(this.terminalService.getSubsystem().name) //here
    .subscribe((data: Command[])=> {
      console.log(data);
      data.forEach((value)=> {
        this.terminalService.setCurrentResult(value.getCommand+'\n'+value.getResult+'\n');
      });
    });
}
catch (exception) {
  console.log(exception);
  this.terminalService.addCurrentResult(this.CONNECTION_ERROR_MSG);
}
}

終端服務.ts

subsystem: Subsystem;

constructor(private httpClient: HttpClient) {}

getSubsystems() {
  return this.httpClient.get('http://localhost:8080/subsystems');
}

getResultsBySubsystem(name: string) {
  return this.httpClient.get('http://localhost:8080/subsystems/'+name+'/result');
}

getSubsystem() {
  console.log('getSubsystem terminal.service invoking');
  return this.subsystem;
}

setSubsystem(subsystem: Subsystem) {
  console.log('setSubsystem terminal.service invoking ');
  this.subsystem=subsystem;
}

will call variable name from subsystem?如何在 child2 的調用子系統中的變量name之前等待獲取請求?

更新

謝謝你的回答。 我試過Resolve ,但有

新控制台

如所見,在 get 之后調用resolve ,盡管this.actr.data ,據我所知,必須調用resolve 使困惑。

來自 terminal.service 的新 getSubsystems

import {map} from 'rxjs/operators';


subsystem: Subsystem;

constructor(private httpClient: HttpClient) {}

getSubsystems() {
    console.log('getSubsystems in terminal.service invoking');
    return this.httpClient.get<Subsystem[]>('http://localhost:8080/subsystems')
      .pipe(map(value=>{console.log(value); return value;}));
  }

孩子1

subsystems: Subsystem[];
currentTabId;

constructor(private terminalService: TerminalService, private actr: ActivatedRoute) {}

ngOnInit() {
    console.log('child1 ngoninit');
    try {
      this.terminalService.setCurrentResult('Connecting...');
      this.actr.data.subscribe((data: []) => { //this
        console.log('get in child1 finished');
        this.subsystems=data;
        console.log(data);
        this.currentTabId=0;
        this.terminalService.setSubsystem(this.subsystems[this.currentTabId]);
      });
    } catch (exception) {
      console.log(exception);
    }
  }

解決服務

export class ResolverService implements Resolve<any>{

  constructor(private terminalService: TerminalService) { }

  resolve(){
    console.log('resolve');
    return this.terminalService.getSubsystems();
  }
}

解析模塊

import {RouterModule, Routes} from '@angular/router';
import {ResolverService} from './services/resolver.service';

const routes: Routes = [
  {
    path: '',
    component: AppComponent,
    resolve: {
      subsystems: ResolverService
    }
  }
];

export const routing = RouterModule.forRoot(routes);

@NgModule({
  declarations: [],
  imports: [CommonModule],
  exports: [RouterModule],
  providers: [ResolverService]
})
export class ResolverModule { }

應用程序模塊

import {ResolverModule} from './resolver.module';
import { routing } from './resolver.module';
import {RouterModule} from '@angular/router';

@NgModule({
  declarations: [
    AppComponent,
    TabsComponent,
    IoComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    BrowserAnimationsModule,
    HttpClientModule,
    routing
  ],
  exports: [RouterModule],
  providers: [ResolverModule],
  bootstrap: [AppComponent]
})
export class AppModule { }

這有什么問題?

我使用APP_INITIALIZER解決了它

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import {APP_INITIALIZER, NgModule} from '@angular/core';
import { AppComponent } from './app.component';
import {FormsModule} from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TabsComponent } from './tabs/tabs.component';
import {HttpClientModule} from '@angular/common/http';
import { IoComponent } from './io/io.component';
import {AppConfig} from './config/app.config';

export function loadConfig(config: AppConfig) {
  return () => config.load();
}

@NgModule({
  declarations: [
    AppComponent,
    TabsComponent,
    IoComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    BrowserAnimationsModule,
    HttpClientModule,
  ],
  bootstrap: [AppComponent],
  providers: [
    AppConfig,
    {provide: APP_INITIALIZER, useFactory: loadConfig, deps: [AppConfig], multi: true}
  ]
})
export class AppModule {
}

創建配置文件並load() function 在加載組件的構造函數之前加載獲取請求

應用程序.config.ts

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Subsystem} from '../data/subsystem';
import {map} from 'rxjs/operators';

@Injectable()
export class AppConfig {

  private subsystems: Subsystem[] = null;
  private subsystem: Subsystem = null;

  constructor(private http: HttpClient) {

  }

  load() {
    return new Promise((resolve) => {
      this.http
        .get('http://localhost:8080/subsystems')
        .pipe(map(value=>value))
        .subscribe((data: Subsystem[]) => {
          this.subsystems = data;
          resolve(true);
        });
    });
  }

  public getSubsystem() {
    return this.subsystem;
  }

  public setSubsystem(subsystem: Subsystem) {
    this.subsystem=subsystem;
  }

  public getSubsystems() {
    return this.subsystems;
  }

  public setSubsystems(subsystems: Subsystem[]) {
    this.subsystems=subsystems;
  }
}

使用初始化數據

tabs.component.ts

import {Component, OnInit} from '@angular/core';
import {Subsystem} from '../data/subsystem';
import {AppConfig} from '../config/app.config';

@Component({
  selector: 'app-tabs-component',
  templateUrl: 'tabs.component.html',
  styleUrls: ['./tabs.component.css'],
})

export class TabsComponent implements OnInit {

  subsystems: Subsystem[];
  subsystem: Subsystem;
  currentTabId;

  constructor(private config: AppConfig) {
  }

  ngOnInit() {
    this.currentTabId=0;
    this.subsystems=this.config.getSubsystems();
    this.config.setSubsystem(this.subsystems[this.currentTabId]);
    this.subsystem=this.config.getSubsystem();
  }

  tabPressed(id) {
    this.currentTabId=id;
    this.config.setSubsystem(this.subsystems[id]);
    this.subsystem=this.config.getSubsystem();
  }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM