NGRX + 解析器不工作:组件似乎在动作完成调度之前加载
NGRX + Resolver not working: Component seems to be loading before action is done dispatching
我正在尝试从路由中获取数据并将数据加载到我的状态中,然后再显示我的详细信息组件,因此我创建了一个解析器。据我所知,我的 get 请求正在运行,但似乎 api 调用是在组件加载后完成的。
@Injectable()
export class WorkOrderDetailResolver implements Resolve<WorkOrder> {
constructor(
private store: Store<fromApp.AppState>
) { }
waitForWorkOrderDataToLoad(route, state) {
this.store.dispatch(new WorkOrderActions.FetchWorkOrderFromAPIByID(+route.params['id']));
return this.store.select(state => state.workOrder.workOrderDetails).pipe(take(1));
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<WorkOrder> | Promise<WorkOrder> | WorkOrder {
return this.waitForWorkOrderDataToLoad(route, state);
}
}
这些是我明确将解析器应用于 WorkOrderDetailsComponent 的路线
const workOrderRoutes: Routes = [
{
path: 'workorders',
component: WorkOrderComponent,
children: [
{ path: 'new', component: WorkOrderEditComponent },
{ path: 'list', component: WorkOrderListComponent },
{ path: ':id', component: WorkOrderDetailComponent, resolve: { workOrderDetails: WorkOrderDetailResolver } },
{ path: ':id/edit', component: WorkOrderEditComponent }
]
}
];
最后是 WorkOrdersDetailComponent 的代码:
@Component({
selector: 'app-work-order-detail',
templateUrl: './work-order-detail.component.html',
styleUrls: ['./work-order-detail.component.css']
})
export class WorkOrderDetailComponent implements OnInit {
private id: number;
workOrder: WorkOrder;
workOrderState: Observable<{workOrders: WorkOrder[]}>;
constructor(private route: ActivatedRoute,
private router: Router,
) { }
ngOnInit() {
console.log(this.route.snapshot.data);
this.workOrder = this.route.snapshot.data.workOrderDetails;
}
onEditWorkOrder() {
this.router.navigate(['edit'], {relativeTo: this.route});
}
}
为了解释我在解析器中的代码的目标是,从我的 API 中调度用于通过 id 获取工作订单的操作并存储它的状态(这有效),一旦完成,并且仅在完成后,return 我存储在状态中的 workOrder 的可观察对象并加载 WorkOrderDetailComponent。
第一次加载路由时视图无法读取 workOrder 的 null 值的错误,但随后发生的是,如果我导航离开并返回页面,workOrder 不再为 null。所以我的猜测是解析器出于某种原因在加载组件之前没有发挥它的魔力?我想要的是 return Observable<{WorkOrder]> 的解析器,以便我可以在视图中异步加载它。
此外,这可能只是我没有正确使用 rxjs 操作符的问题,我很难理解 observables 的工作原理以及这些操作符应该如何链接。如果是这样的话,请指教哪里不对,为什么。
谢谢!
你应该等到选择器returns一个值
this.store.pipe(
select(state => state.workOrder.workOrderDetails),
filter(details => !!details),
take(1)
);
请注意,我还在商店中使用 select
运算符而不是 select
方法。这是因为商店上的 select
方法已弃用,将来会被删除。
我正在尝试从路由中获取数据并将数据加载到我的状态中,然后再显示我的详细信息组件,因此我创建了一个解析器。据我所知,我的 get 请求正在运行,但似乎 api 调用是在组件加载后完成的。
@Injectable()
export class WorkOrderDetailResolver implements Resolve<WorkOrder> {
constructor(
private store: Store<fromApp.AppState>
) { }
waitForWorkOrderDataToLoad(route, state) {
this.store.dispatch(new WorkOrderActions.FetchWorkOrderFromAPIByID(+route.params['id']));
return this.store.select(state => state.workOrder.workOrderDetails).pipe(take(1));
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<WorkOrder> | Promise<WorkOrder> | WorkOrder {
return this.waitForWorkOrderDataToLoad(route, state);
}
}
这些是我明确将解析器应用于 WorkOrderDetailsComponent 的路线
const workOrderRoutes: Routes = [
{
path: 'workorders',
component: WorkOrderComponent,
children: [
{ path: 'new', component: WorkOrderEditComponent },
{ path: 'list', component: WorkOrderListComponent },
{ path: ':id', component: WorkOrderDetailComponent, resolve: { workOrderDetails: WorkOrderDetailResolver } },
{ path: ':id/edit', component: WorkOrderEditComponent }
]
}
];
最后是 WorkOrdersDetailComponent 的代码:
@Component({
selector: 'app-work-order-detail',
templateUrl: './work-order-detail.component.html',
styleUrls: ['./work-order-detail.component.css']
})
export class WorkOrderDetailComponent implements OnInit {
private id: number;
workOrder: WorkOrder;
workOrderState: Observable<{workOrders: WorkOrder[]}>;
constructor(private route: ActivatedRoute,
private router: Router,
) { }
ngOnInit() {
console.log(this.route.snapshot.data);
this.workOrder = this.route.snapshot.data.workOrderDetails;
}
onEditWorkOrder() {
this.router.navigate(['edit'], {relativeTo: this.route});
}
}
为了解释我在解析器中的代码的目标是,从我的 API 中调度用于通过 id 获取工作订单的操作并存储它的状态(这有效),一旦完成,并且仅在完成后,return 我存储在状态中的 workOrder 的可观察对象并加载 WorkOrderDetailComponent。
第一次加载路由时视图无法读取 workOrder 的 null 值的错误,但随后发生的是,如果我导航离开并返回页面,workOrder 不再为 null。所以我的猜测是解析器出于某种原因在加载组件之前没有发挥它的魔力?我想要的是 return Observable<{WorkOrder]> 的解析器,以便我可以在视图中异步加载它。
此外,这可能只是我没有正确使用 rxjs 操作符的问题,我很难理解 observables 的工作原理以及这些操作符应该如何链接。如果是这样的话,请指教哪里不对,为什么。
谢谢!
你应该等到选择器returns一个值
this.store.pipe(
select(state => state.workOrder.workOrderDetails),
filter(details => !!details),
take(1)
);
请注意,我还在商店中使用 select
运算符而不是 select
方法。这是因为商店上的 select
方法已弃用,将来会被删除。