我在Angular上有一个应用程序。我有三个组件: root , child1 (tabs.component.ts)和 child2 (io.component.ts)。另外,我有一项将get和post请求发送到tomcat服务器的服务。
在 child1 中,我有一个ngoninit,在其中我调用服务方法get。我在 child2 中也有ngoninit。 child1 中的Ngoninit首先启动。在 child1 中,从服务器获取数据的请求太慢,并且 child2 的ngoninit在get.subscribe(data=>this.data=data)
之前开始。
所以问题在于 child2 的ngoninit方法使用了此data
,并且由于get请求未返回数据,但它仍填充了undefined
。
所以,我有下一个序列:
要使用async
,await
,toPromise()
,但是它不起作用,在完成加载的所有情况下, child2 中的ngoninit都会被加载。
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);
}
}
terminal.service.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;
}
在 child2 的ngoninit从子系统调用变量name
之前,如何等待获取请求?
thx为您的答案。我已经尝试过Resolve
,但是有
如图所示,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;}));
}
child1
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);
}
}
resolve.service
export class ResolverService implements Resolve<any>{
constructor(private terminalService: TerminalService) { }
resolve(){
console.log('resolve');
return this.terminalService.getSubsystems();
}
}
resolve.module
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 { }
这怎么了?
答案 0 :(得分:0)
我用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()
函数以在加载组件的构造函数之前加载get请求
app.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();
}
}