• [NgRx] NgRx Data Fetching Solution


    We have a reoslver, which everytime we want visit '/courses' route, it will be triggered, then api will be called, data will be loaded.

    import { Injectable } from "@angular/core";
    import {
      Resolve,
      ActivatedRouteSnapshot,
      RouterStateSnapshot
    } from "@angular/router";
    import { Observable } from "rxjs";
    import { Store } from "@ngrx/store";
    import { AppState } from "../reducers";
    import { CoursesAction } from "./actions-types";
    import { tap, first, finalize } from "rxjs/operators";
    import { adapter } from "./reducers/courses.reducers";
    
    @Injectable()
    export class CoursesResolver implements Resolve<any> {
      loading = false;
      constructor(private store: Store<AppState>) {}
    
      resolve(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): Observable<any> {
        return this.store.pipe(
          tap(() => {
            if (!this.loading) {
              this.loading = true;
              this.store.dispatch(CoursesAction.loadAllCourse());
            }
          }),
          // this resolve need to complete, so we can use first()
          first(),
          finalize(() => (this.loading = false))
        );
      }
    }

    So how to prevent reload the data if we have already loaded the data once?

    Add one prop into state: 'allCoursesLoaded'

    import { Course, compareCourses } from "../model/course";
    import { EntityState, createEntityAdapter } from "@ngrx/entity";
    import { createReducer, on } from "@ngrx/store";
    import { CoursesAction } from "../actions-types";
    /*
    export interface CoursesState {
      entities: { [key: number]: Course };
      ids: number[];
    }*/
    
    export interface CoursesState extends EntityState<Course> {
      /**Extend the entity here */
      allCoursesLoaded: boolean;
    }
    
    export const adapter = createEntityAdapter<Course>({
      sortComparer: compareCourses
      // selectId: course => course.id // NgRx use 'id' by default
    });
    
    export const initCoursesState = adapter.getInitialState({
      allCoursesLoaded: false
    });
    
    export const coursesReducer = createReducer(
      initCoursesState,
      on(CoursesAction.allCoursesLoaded, (state, action) =>
        adapter.addAll(action.courses, { ...state, allCoursesLoaded: true })
      )
    );
    
    export const { selectAll } = adapter.getSelectors();

    Now we can modify the resolver:

    import { Injectable } from "@angular/core";
    import {
      Resolve,
      ActivatedRouteSnapshot,
      RouterStateSnapshot
    } from "@angular/router";
    import { Observable } from "rxjs";
    import { Store, select } from "@ngrx/store";
    import { AppState } from "../reducers";
    import { CoursesAction } from "./actions-types";
    import { tap, first, finalize, filter } from "rxjs/operators";
    import { adapter } from "./reducers/courses.reducers";
    import { selectAllCoursesLoaded } from "./courses.selectors";
    
    @Injectable()
    export class CoursesResolver implements Resolve<any> {
      loading = false;
      constructor(private store: Store<AppState>) {}
    
      resolve(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
      ): Observable<any> {
        return this.store.pipe(
          select(selectAllCoursesLoaded),
          tap(courseLoaded => {
            if (!this.loading && !courseLoaded) {
              this.loading = true;
              this.store.dispatch(CoursesAction.loadAllCourse());
            }
          }),
          // this resolve need to complete, so we can use first()
          filter(courseLoaded => courseLoaded),
          first(),
          finalize(() => (this.loading = false))
        );
      }
    }
  • 相关阅读:
    模板 素数筛选
    模板 BFS
    模板 01背包
    模板 计算1的个数
    模板 最长公共子序列
    模板 最长递增子序列
    模板 最长公共递增子序列
    zjuoj 3602 Count the Trees
    zjuoj 3608 Signal Detection
    zjuoj 3606 Lazy Salesgirl
  • 原文地址:https://www.cnblogs.com/Answer1215/p/11623733.html
Copyright © 2020-2023  润新知