在使用 URL 参数加载页面之前等待 ngrx 操作
Waiting for ngrx action before loading page with URL parameter
我正在使用 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 后再加载我的页面?
您可以 select 商店中的文档并订阅它并从那里发出您的操作:
ngOnInit() {
this.store.select("documents").subscribe(documents => {
this.paramSubscription = this.route.params
.select<string>('id')
.map((id) => new SelectAction(id))
.subscribe(this.store);
});
}
我会使用 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();
}
您需要一个解析器。解析器在完成导航操作之前等待数据可用。
@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 } }
];
更多关于路由器解析的信息
我正在使用 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 后再加载我的页面?
您可以 select 商店中的文档并订阅它并从那里发出您的操作:
ngOnInit() {
this.store.select("documents").subscribe(documents => {
this.paramSubscription = this.route.params
.select<string>('id')
.map((id) => new SelectAction(id))
.subscribe(this.store);
});
}
我会使用 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();
}
您需要一个解析器。解析器在完成导航操作之前等待数据可用。
@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 } }
];
更多关于路由器解析的信息