我正在使用ngrx构建ng2应用程序。启动应用程序时,会调用Web服务来获取初始数据,一旦获取此数据,我就会创建 INIT_DONE 操作。
我的州看起来像这样:
export interface State {
documents: Document[];
selectedDocument: Document
}
当我转到页面/ mypage / 456,其中456是url参数时,我需要获取一些获取的数据,因此我得到这样的URL参数:
ngOnInit() {
this.paramSubscription = this.route.params
.select<string>('id')
.map((id) => new SelectAction(id))
.subscribe(this.store);
}
SELECT_ACTION 在获取的数据中找到元素并设置selectedDocument
。问题是 SELECT_ACTION 是在 INIT_DONE 之前创建的,此时documents
为空。
如何在加载页面之前等待 INIT_DONE ?
答案 0 :(得分:6)
我会使用combineLatest运算符,因为它结合了多个源流的最新值。另外,我要仔细检查文档是否已设置(这里我假设它是一个数组)使用过滤器。
ngOnInit() {
this.subscription = Observable.combineLatest(
this.store.select("documents")
.filter(documents => documents.length > 0),
this.paramSubscription = this.route.params
.select<string>('id')
)
.map((combinedData: [Object[], string]) => combinedData[1])
.subscribe(this.store);
}
还将订阅分配给变量,以便您可以在销毁组件时取消订阅。否则,您的订阅将在组件被销毁后出现,并且您的操作可能仍会被释放:
ngOnDestroy() {
this.subscription.unsubscribe();
}
答案 1 :(得分:4)
你需要一个解析器。在完成导航操作之前,解析器会等待数据可用。
@Injectable()
export class DocumentsResolver implements Resolve {
constructor(
private store: Store
) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Hero> {
// take id from snapshot
const id = route.params['id'];
// start with the document list
return this.store.select('documents')
// wait until there is data available
.filter(documents => documents && documents.length > 0)
// then produce the selected document
.mergeMapTo(this.store.select('selectedDocument'));
}
}
路线配置:
export const DocumentsRoutes: RouterConfig = [
{ path: 'documents/:id', component: DocumentsDetailComponent, resolve: { document: DocumentsResolver } }
];
有关路由器解析的更多信息here
答案 2 :(得分:0)
您可以从商店中选择文档并订阅它并从那里发出您的操作:
ngOnInit() {
this.store.select("documents").subscribe(documents => {
this.paramSubscription = this.route.params
.select<string>('id')
.map((id) => new SelectAction(id))
.subscribe(this.store);
});
}