【发布时间】:2020-03-04 16:00:54
【问题描述】:
总结
我在 Angular 上有一个应用程序。我有三个组件:root、child1 (tabs.component.ts) 和 child2 (io.component.ts)。另外,我有一个向 tomcat 服务器发送 get 和 post 请求的服务。
在 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之前如何等待get请求?
更新
感谢您的回答。我试过Resolve,但是有
如所见,resolve 在 get 之后调用,但 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 { }
app.module
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 { }
这是怎么回事?
【问题讨论】:
-
我编写了一个名为 RxCache 的库来处理这类事情。在这里阅读它medium.com/@adrianbrand/…
-
这正是 Ngrx、Ngxs、秋田等状态系统存在的原因。
-
在组件加载前使用
reslove加载数据
标签: javascript angular typescript