如何仅角度地从服务器首次获取数据?

时间:2018-07-03 09:56:29

标签: angular ngrx

能否请您告诉我仅第一次从服务器获取数据并显示到屏幕的方法。但是如果用户再次访问或者再次加载组件,它将从存储中获取数据。我正在将redux与ngrx配合使用。

我制作了一个示例应用程序,其中有两个按钮home screennew 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))
  }
}

1 个答案:

答案 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属性而被“缓存”。