我在Angular 2.3.1上,我对Angular和基于事件的编程都很新。我有两个订阅,route.params.subscribe
和engineService.getEngines()
。在我的onInit
我希望在getEngineName
和this.route.params.subscribe
完成后致电this.engineService.getEngines().subscribe
。
原因:getEngineName
函数取决于queryParams中的engineId
和engines
调用完成后填充的getEngines()
数组。
我确实看过flatMap
和switchMap
,但我并没有完全理解它们。
这是组件中的代码:
export class ItemListComponent implements OnInit {
items: Item[];
engines: Engine[];
private engineId: number;
constructor(
private router: Router,
private route: ActivatedRoute,
private itemService: ItemService,
private engineService: EngineService
) {}
ngOnInit() {
this.route.params.subscribe((params: Params) => {
this.engineId = +params['engineId'];
// itemService is irrelevant to this question
this.itemService.getItems({engineId: this.engineId})
.subscribe((items: Item[]) => {
this.items = items;
});
});
this.engineService.getEngines()
.subscribe(engines => this.engines = engines);
// This should only run after engineId and engines array have been populated.
this.getEngineName(this.engineId);
}
getEngineName(engineId: number) {
this.engines.find((engine) => {
return engine.id === engineId;
})
}
}
答案 0 :(得分:2)
为什么不在route.params
回调中移动逻辑?
this.route.params.subscribe((params: Params) => {
this.engineId = +params['engineId'];
// itemService is irrelevant to this question
this.itemService.getItems({engineId: this.engineId})
.subscribe((items: Item[]) => {
this.items = items;
});
//this.engineId is defined here (1)
this.engineService.getEngines()
.subscribe((engines) => {
this.engines = engines;
//this.engines is defined here (2)
this.getEngineName(this.engineId);
});
});
flatMap
和forkJoin
:
this.route.params.flatMap((params: Params) => {
this.engineId = +params['engineId'];
return Observable.forkJoin(
this.itemService.getItems({engineId: this.engineId}),
this.engineService.getEngines()
)
}).subscribe((data)=>{
let items = data[0];
let engines = data[1];
this.items = items;
this.engines = engines;
this.getEngineName(this.engineId);
});
答案 1 :(得分:0)
switchMap
。
this.route.params.pluck('engineId') //pluck will select engineId key from params
.switchMap(engineId => {
this.getItems(engineId);
return this.engineService.getEngines().map(engines => {
/*this.engineService.getEngines() emits the list of engines.
Then use map operator to convert the list of engines to engine we are looking for
*/
return engines.find((engine) => {
return engine.id === engineId;
})
})
}).subscribe(engine => {
//engine
})
getItems(engineId) {
this.itemService.getItems({engineId: engineId})
.subscribe((items: Item[]) => {
this.items = items;
});
}
假设params中的engineId发生变化,第一个可观察的this.route.params.pluck('engineId')
将发出数据,这将导致下一个可观察的this.engineService.getEngines()
被触发。现在假设在此observable发出数据之前路由发生了变化。在这里,您需要取消getEngines
observable以防止出错。这是由switchMap
完成的。
switchMap
将取消内部observable。
PS:我避免保留this.engineId
等任何状态。