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))
);
}
}

[NgRx] NgRx Data Fetching Solution - How to Load Data Only If Needed的更多相关文章

  1. LOAD DATA INFILE Syntax--官方

    LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name' [REPLACE | IGNORE] INTO TABLE tbl_n ...

  2. mysql迁移-----拷贝mysql目录/load data/mysqldump/into outfile

    摘要:本文简单介绍了mysql的三种备份,并解答了有一些实际备份中会遇到的问题.备份恢复有三种(除了用从库做备份之外), 直接拷贝文件,load data 和 mysqldump命令.少量数据使用my ...

  3. JDBC使用MYSQL的LOAD DATA LOACAL INFILE和LOAD DATA INFILE

    MYSQL的LOAD方法都必须建立在mysql服务允许使用该命令的情况下: 开启该命令的方法: 1.在实例对应的my.cnf(windows为my.ini)中添加一行local-infile=1(默认 ...

  4. MySQL基础之---mysqlimport工具和LOAD DATA命令导入文本文件

     1.mysqlimport工具的使用 看一下命令的使用方法: shell > mysqlimport -u root -p [--LOCAL] DBname File [option] --f ...

  5. load data infile出现“ERROR 13 (HY000): Can't get stat of '/tmp/test2.txt' (Errcode: 2)”问题

    用load data infile导数据到mysql数据库出现这个该问题,解决方法如下: 安全起见,连接mysql的语句需要添加–local-infile, mysql -hlocalhost -ur ...

  6. mysql数据库LOAD DATA INFILE Syntax

    1.LOAD DATA INFILE用来把一个文本文件里的内容高速写入到MySQL表里,它和SELECT ... INTO FILE的操作是对应的,一个导入.一个导出.使用LOAD DATA INFI ...

  7. MySQL 之 LOAD DATA INFILE 快速导入数据

    SELECT INTO OUTFILE > help select; Name: 'SELECT' Description: Syntax: SELECT [ALL | DISTINCT | D ...

  8. mysql load data 乱码

    解决方案: http://stackoverflow.com/questions/26256421/sql-load-data-infile-utf8-issue 即: load data local ...

  9. Mybatis拦截器 mysql load data local 内存流处理

    Mybatis 拦截器不做解释了,用过的基本都知道,这里用load data local主要是应对大批量数据的处理,提高性能,也支持事务回滚,且不影响其他的DML操作,当然这个操作不要涉及到当前所lo ...

随机推荐

  1. Java开发笔记(一百二十五)AWT图像加工

    前面介绍了如何使用画笔工具Graphics绘制各种图案,然而Graphics并不完美,它的遗憾之处包括但不限于:1.不能设置背景颜色:2.虽然提供了平移功能,却未提供旋转功能与缩放功能:3.只能在控件 ...

  2. c++基础(五)——关联容器

    1.关联容器 关联容器中的元素时按照关键字来保存和访问的,与之相对的,顺序容器中的元素时按它们在容器中的位置来顺序保存和访问的.两个主要关联容器是 map 和 set.标准库提供了8个关联容器,这8个 ...

  3. 用外部按钮打开DATETIMEPICKER下拉日期选择窗口

    https://www.cnblogs.com/gaodu2003/archive/2009/08/10/1543115.html 方法一: SendMessage(DateTimePicker1.H ...

  4. Python-12-装饰器

    一.定义 器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 原则: 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不修 ...

  5. python函数知识六 内置函数二、匿名函数与内置函数三(重要)

    19.内置函数二 abs():绝对值 lst = [1,2,-3,1,2,-5] print([abs(i) for i in lst]) enumerate("可迭代对象",&q ...

  6. 如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀)

    原文:如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀) 我们都知道可以通过在 Visual Studio 中设置输出路径(OutputPath)来更改项目输 ...

  7. js 简单的滑动1

    js 简单的滑动教程(一)   作者:Lellansin 转载请标明出处,谢谢 首先我们要实现一个简单的滑动,三张图.点击左边向左滑动,点右向右滑,碰到临界值的时候就不能滑动. 这个简单滑动的原理是, ...

  8. 【openshift】在Openshift上通过yaml部署应用

    在Openshift上通过yaml部署应用 1.通过直接执行yaml 通过如下命令直接执行 oc create -f nginx.yml nginx.yml apiVersion: v1 items: ...

  9. python3基础之“小练习(1)”

    (一)打印3个不同的字符 # a=int("123") # b="123" # c=1.2 # print(type(a),a) # print(type(b) ...

  10. 点击其它位置,div下拉菜单消失

    接下拉菜单那一篇: 加上点击其它位置,下拉菜单消失. 纯js写法: window.document.addEventListener('click', function(e) { var e = e ...