ngrx/store effects 使用总结2:列表展示
第一个计数器案例:http://www.cnblogs.com/axel10/p/8589122.html
完成了计数器案例后,现在开始比较能够完整的展示angular2+开发流程的案例:在线获取用户列表并展示,包含点击删除功能。希望在开始之前,你对typescript和rxjs有一定了解。
再重复一遍开发流程:
开始 -> 编写数据模型 -> 编写action -> 编写redurces并配置到相应module -> 编写services -> 编写effects并配置到相应module -> 创建组件 -> 组件绑定数据模型 -> 渲染
第一步:编写数据模型(app/models/user.ts)
export class User { id: number; name: string; }
第二步:编写action(app/actions/num.ts)
import {Action} from '@ngrx/store';
import {User} from '../models/user'; export enum ListActionType {
Load = 'LOAD',
LoadSuccess = 'LOAD_SUCCESS',
RemoveUser = 'REMOVE_USER',
RemoveUserSuccess = 'REMOVE_USER_SUCCESS',
RemoveUserError = 'REMOVE_USER_ERROR'
} export class Load implements Action {
readonly type = ListActionType.Load;
} export class LoadSuccess implements Action {
readonly type = ListActionType.LoadSuccess; constructor(public payload: User[]) {
}
} export class RemoveUser implements Action {
readonly type = ListActionType.RemoveUser; constructor(public payload: number) {
}
} export class RemoveUserSuccess implements Action {
readonly type = ListActionType.RemoveUserSuccess;
} export class RemoveUserError implements Action {
readonly type = ListActionType.RemoveUserError;
}
第三步:编写redurcers(app/redurces/list.ts)
import {Action} from '@ngrx/store'; import {User} from '../models/user'; import {ListActionType, LoadSuccess, RemoveUser} from '../actions/list'; export interface State { loading: boolean; loaded: boolean; list: User[]; } const initialState: State = { loading: false, loaded: false, list: [] }; export const list = (state = initialState, action: Action) => { switch (action.type) { case ListActionType.Load: console.log('load....'); return { ...state, loading: true, }; case ListActionType.LoadSuccess: console.log('load success'); const myA = (<LoadSuccess>action).payload; console.log(myA); return { ...state, loaded: true, loading: false, list: myA }; case ListActionType.RemoveUser: console.log('remove user'); const userId = (<RemoveUser>action).payload; state.list = state.list.filter(function (item) { return item.id !== userId; }); return {...state}; default: return state; } };
配置redurcer(app/app.module.ts)
imports: [ BrowserModule, RouterModule.forRoot(routes), StoreModule.forRoot({ modelNum, list}), //配置redurcer ],
第四步:编写services(app/services/ListService.ts)
import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; import {Observable} from 'rxjs/Observable'; import {User} from '../models/user'; @Injectable() export class ListService { public getList(): Observable<any> { return this.http.get<{ users: User[] }>('/api/users.json'); } public removeUser(): Observable<any> { return Observable.create(function (observer) { observer.next('true'); }); } constructor(private http: HttpClient) { } }
第五步:编写effects:
import {Injectable} from '@angular/core'; import {Actions, Effect, ofType} from '@ngrx/effects'; import {Observable} from 'rxjs/Observable'; import {Action} from '@ngrx/store'; import {ListActionType, Load, LoadSuccess, RemoveUser, RemoveUserError, RemoveUserSuccess} from '../actions/list'; import {catchError, map, switchMap} from 'rxjs/operators'; import {ListService} from '../services/ListService'; import {of} from 'rxjs/observable/of'; @Injectable() export class ListEffects { @Effect() loadList$: Observable<Action> = this.action$.pipe( //rxjs写法。loadList$是effect名,在外部没有用到,可以随便起。 ofType<Load>(ListActionType.Load), switchMap(action => { return this.listService.getList().pipe(map( users => { return new LoadSuccess(users); } )); }) ); @Effect() removeUser$: Observable<Action> = this.action$.pipe( ofType<RemoveUser>(ListActionType.RemoveUser), switchMap(_ => { return this.listService.removeUser().pipe( map(res => { console.log(res); if (res === 'true') { return new RemoveUserSuccess(); } else { return new RemoveUserError(); } }), catchError(err => of(new RemoveUserError())) ); }) ); constructor(private action$: Actions, private listService: ListService) { } }
记得在app.module.ts配置effects和HttpClient:
imports: [ BrowserModule, RouterModule.forRoot(routes), StoreModule.forRoot({modelNum, list}), EffectsModule.forRoot([ListEffects]), HttpClientModule ],
第六步:创建组件
ng g component list
第七步:组件绑定数据模型(连带完成第八步)
组件ts文件:
import {Component, OnInit} from '@angular/core'; import {Store} from '@ngrx/store'; import * as list from '../actions/list'; import {State} from '../reducers/list'; import {User} from '../models/user'; @Component({ selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.scss'] }) export class ListComponent implements OnInit { public list: User[]; constructor(private store: Store<any>) { this.store.select('list').subscribe(_list => { if (_list) { console.log(_list); console.log(_list.list); this.list = _list.list; } }); } removeUser(id) { console.log(id); this.store.dispatch(new list.RemoveUser(id)); } ngOnInit() { this.store.dispatch(new list.Load()); } }
组件html文件:
<div> list 请尝试点击上半部分的li。 <ul> <li *ngFor="let item of list" (click)="removeUser(item.id)">{{item.name}}</li> </ul> <app-list-body></app-list-body> <br/> <a routerLink="/model">to counter demo</a> </div>
最后配置路由:
import {Routes} from '@angular/router'; import {IndexComponent} from './index/index.component'; import {ModelDemoComponent} from './model-demo/model-demo.component'; import {ListComponent} from './list/list.component'; export const routes: Routes = [ { path: 'list', component: ListComponent }, { path: 'model', component: ModelDemoComponent }, { path: '**', redirectTo: 'list' } ];
到此本案例结束。如果想要更加复杂的案例可以到ngrx的github获取。https://github.com/ngrx/platform
ngrx/store effects 使用总结2:列表展示的更多相关文章
- ngrx/store effects 使用总结1:计数器
本教程案例github:https://github.com/axel10/ngrx_demo-counter-and-list angular2+ 的学习成本应该是三大框架中最高的一个,教程及案例稀 ...
- [Angular2] @Ngrx/store and @Ngrx/effects learning note
Just sharing the learning experience related to @ngrx/store and @ngrx/effects. In my personal opinio ...
- Angular应用架构设计-3:Ngrx Store
这是有关Angular应用架构设计系列文章中的一篇,在这个系列当中,我会结合这近两年中对Angular.Ionic.甚至Vuejs等框架的使用经验,总结在应用设计和开发过程中遇到的问题.和总结的经验, ...
- Vuex 教程案例:计数器以及列表展示
本案例github:https://github.com/axel10/Vuex_demo-Counter-and-list 本篇教程将以计数器及列表展示两个例子来讲解Vuex的简单用法. 从安装到启 ...
- Winform开发主界面菜单的动态树形列表展示
我在之前很多文章里面,介绍过Winform主界面的开发,基本上都是标准的界面,在顶部放置工具栏,中间区域则放置多文档的内容,但是在顶部菜单比较多的时候,就需要把菜单分为几级处理,如可以在顶部菜单放置一 ...
- [Angular 2] ngrx/store
@ngrx/store builds on the concepts made popular by Redux and supercharges it with the backing of RxJ ...
- [Angular 2] Using ngrx/store and Reducers for Angular 2 Application State
ngrx/store is a library that simplifies common RxJS patterns for managing state and gives you an eas ...
- JSP中列表展示,隔行变色以及S标签的使用
1.java代码 /** * 列表展示,隔行变色以及S标签的使用 * * @return */ public String list() { List<User> list = new A ...
- NgRx/Store 4 + Angular 5使用教程
这篇文章将会示范如何使用NgRx/Store 4和Angular5.@ngrx/store是基于RxJS的状态管理库,其灵感来源于Redux.在NgRx中,状态是由一个包含action和reducer ...
随机推荐
- notification 使用的基本方法
当某个应用程序希望向用户发出一些提示信息,而应用程序又不在前台,可以借助Notification来实现.发出一条通知后,手机最上方额通知栏会显示一个图标,下来状态栏以后可以看到详细内容. 一.通知的基 ...
- CTU Open Contest 2017
这场题很水.水题我就懒得贴了. B - Pond Cascade 优先队列维护这个水池需要多少时间 或者 直接扫一遍. #include <cstdio> #include <cst ...
- 2018 Multi-University Training Contest 1 H - RMQ Similar Sequence(HDU - 6305 笛卡尔树)
题意: 对于一个序列a,构造一个序列b,使得两个序列,对于任意的区间 [l, r] 的区间最靠近左端点的那个最大值的位置,并且序列 b 满足 0 < bi < 1. 给定一个序列 a ,求 ...
- RAID与LVM磁盘阵列技术
RAID(Redundant Array of Independent Disks,独立冗余磁盘阵列) RAID概念: RAID技术通过把多个硬盘设备组合成一个容量更大.安全性更好的磁盘阵列,并把数据 ...
- Ubuntu18.04安装docker、docker-compose、
Ubuntu18.04下Docker CE安装 Docker版本分为两个:Docker Community Edition (CE)和 Docker Enterprise Edition (EE).D ...
- 软工实践 - 第九次作业 Alpha 冲刺 (1 / 10)
队名:起床一起肝活队 组长博客:https://www.cnblogs.com/dawnduck/p/9949350.html 作业博客:(班级博客本次作业的链接) 组员情况 组员1(队长):白晨曦 ...
- 树中两个结点的最低公共祖先--java
题目:对于任意一个树,不仅仅限于二叉树,求树中两个结点的最低公共祖先结点. 解析:对于任意一棵树,显然并不局限于二叉树,也就是说树的非叶子结点可能存在多个子节点.所以,我们可以定义两个链表结构,存储这 ...
- WS-*协议栈及相关概念
1. 什么是WS-Security? WS-Security 是一个 SOAP 的扩展,它提供了对 SOAP 消息的认证和加密. 在介绍 WS-Security 之前,我们有必要了解一下 WS-Sec ...
- [LOJ#2327]「清华集训 2017」福若格斯
[LOJ#2327]「清华集训 2017」福若格斯 试题描述 小d是4xx9小游戏高手. 有一天,小d发现了一个很经典的小游戏:跳青蛙. 游戏在一个 \(5\) 个格子的棋盘上进行.在游戏的一开始,最 ...
- BZOJ2194 快速傅立叶之二 【fft】
题目 请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5. a,b中的元素均为小于等于100的非负整数. 输入格式 ...