能否请您告诉我仅第一次从服务器获取数据并显示到屏幕的方法。但是如果用户再次访问或者再次加载组件,它将从存储中获取数据。我正在将redux与ngrx配合使用。
我制作了一个示例应用程序,其中有两个按钮home screen
和new screen
主屏幕上,我会显示来自server
的列表。当我单击new screen
按钮并再次返回主屏幕时,它会再次服务器并获取数据。我不想再次点击。我想从store
获取数据。我将如何获取
这是我的code
(不要在chrome stackblitz中打开此链接,在chrome中有问题)
export class ListComponent implements OnInit {
products$: Observable<Product[]>;
constructor(private productService: ProductService,
private store: Store<fromApp.ProductState>,
private router : Router
) {}
ngOnInit() {
this.store.dispatch(new productActions.Load());
this.products$ = this.store.pipe(select(fromProduct.getProducts))
}
}
答案 0 :(得分:3)
在您的情况下,我的商店内可能会有一个属性,该属性指示数据是否已加载,例如loaded
。首次调度将要在效果中获取数据的动作时,当数据返回时,您还需要将此loaded
属性设置为true
。默认值为false
。然后,您可以在效果内部使用withLatestFrom
并选择loaded
属性。如果将其设置为true
,请不要执行任何操作;如果将其设置为false
,请去获取数据。
首先,更改您的ProductState
并引入一个loaded
属性:
export interface ProductState {
toggleCheckBox: boolean,
products: Product[],
loaded: boolean;
error: string
}
const initialState: ProductState = {
toggleCheckBox: true,
products: [],
loaded: false,
error: ''
};
在化简器的LoadSuccess
上,将loaded
属性设置为true
:
case ProductActionTypes.LoadSuccess:
return {
...state,
products: [...action.payload],
loaded: true,
error: ''
}
现在,在效果内部,检查loaded
属性,然后根据其值获取数据:
@Effect()
loadProduct$: Observable<Action> = this.action$.pipe(
ofType(productAction.ProductActionTypes.Load),
withLatestFrom(this.store.pipe(select(fromProduct.getLoaded))),
switchMap(([, loaded]) => {
if (loaded) {
return empty();
}
return this.productService.getProducts().pipe(
map((products) => {
return new productAction.LoadSuccess(products)
}),
catchError(err => of(new productAction.LoadFail(err)))
)
})
);
这意味着,您的效果只会在尚未加载数据时提取数据,这由loaded
上的ProductState
属性指示。
查看此StackBlitz可以看到它的实际效果。打开开发人员控制台的“网络”标签,以验证该请求仅被触发一次,然后由于loaded
属性而被“缓存”。