最新消息:XAMPP默认安装之后是很不安全的,我们只需要点击左方菜单的 "安全"选项,按照向导操作即可完成安全设置。

ngrx/store 之報告篇

XAMPP下载 文, 员 37浏览 0评论
 ngrx/store 之報告篇
今天開始 今天完成

今天目標:完成報告有關的 Action, Reducer, Effects, Selector

報告篇 - Action
第一步: src/app/store/actions 下建立檔案

ng generate class report.actions –spec
第二步:修改 report.actions.ts

import { Action } from ’@ngrx/store’;
import { Report } from ’../../models’;

// define Actions type
export const GETREPORT = ’[report] GETREPORT’;
export const GETREPORT_SUCCESS = ’[report] GETREPORT_SUCCESS’;
export const GETREPORT_FAIL = ’[report] GETREPORT_FAIL’;

export const RESET_REPORT = ’[report] RESET_REPORT’;        // reset to initial state

// define Actions classes
export class getReportAction implements Action {
readonly type = GETREPORT;
}
export class getReportSuccessAction implements Action {
readonly type = GETREPORT_SUCCESS;
constructor(public payload: Report[]) { }
}
export class getReportFailAction implements Action {
readonly type = GETREPORT_FAIL;
constructor(public payload: any) { }
}
export class resetReportAction implements Action {
readonly type = RESET_REPORT;
}
export type ReportActions
= getReportAction
| getReportSuccessAction
| getReportFailAction
| resetReportAction;

很簡單的動作, GETREPORT 預備給 Effects 用來接後端的資料,RESET 重新把 Report 歸零,預備給使用者登出的時候用
第三步:修改 src/app/store/actions/index.ts

export * from ’./user.actions’;
export * from ’./router.actions’;
export * from ’./report.actions’;
報告篇 - Reducer
第一步:在 src/app/store/reducers 下建立檔案

ng generate class report.reducers –spec
第二步:修改 report.reducers.ts

import { Action } from ’@ngrx/store’;
import * as actions from ’../actions’;
import { Report } from ’../../models’;

export interface ReportState {
reports: Report[];
}
export const initialState: ReportState = {
reports: []
}
export function reducer(state: ReportState = initialState, action: actions.ReportActions): ReportState {
switch (action.type) {
case actions.RESET_REPORT:
return initialState;
case actions.GETREPORT_SUCCESS:
return { …state, reports: action.payload };
default:
return state;
}
}
// for selector
export const getReports = (state: ReportState) => state.reports;
第三步:修改 src/app/store/reducers/index.ts

import { ActionReducerMap } from ’@ngrx/store’;
import * as user from ’./user.reducers’;
import * as router from ’./router.reducers’;
import * as report from ’./report.reducers’;

export interface State {
user: user.UsersState;

     router: router.RouterState;
report: report.ReportState;
}
export const reducers: ActionReducerMap<State> = {
user: user.reducer,
router: router.reducer,
report: report.reducer
}
export { CustomeSerializer } from ’./router.reducers’;
將 report 將入原本的 State 跟 reducers

報告篇 - Effects
第一步:在 src/app/store/effects 下建立檔案

ng generate class report.effects –spec
第二步:修改 report.effects.ts

import { Injectable } from ’@angular/core’;
import { Action } from ’@ngrx/store’;
import { Effect, Actions } from ’@ngrx/effects’;

import { Observable } from ’rxjs/Observable’;
import ’rxjs/add/operator/switchMap’;
import { of } from ’rxjs/observable/of’;
import { map, catchError } from ’rxjs/operators’;

import * as actions from ’../actions’;
import { ReportsService } from ’../../member/services/reports.service’;
import { Report, Response } from ’../../models’;

@Injectable()
export class ReportEffects {
constructor(
private action$: Actions,
private reportsService: ReportsService
) { }

@Effect()
getReportEffect$: Observable<Action> = this.action$.ofType(actions.GETREPORT)
.switchMap(() => {
return this.reportsService.getReportsFromServer().pipe(
map((res: Response) => {
if (res.success) {
return new actions.getReportSuccessAction(res.payload);
} else {
return new actions.getReportFailAction(res.payload);
}
}),
catchError(err => of(new actions.getReportFailAction(err))),
)
});
}
這裡只有一個 effect,也就是 getReportEffect$
當監聽到 GETREPORT 的動作時,用 switchMap 高階運算子來觀察 reportService.getReportsFromServer(),請參考 [ngrx/store -5] 高階 (High Order) Observable
成功的話,分派一個 getReportSuccessAction(),否則分派一個 getReportFailAction()
第三步:修改 src/app/store/effects/index.ts
import { UserEffects } from ’./user.effects’;
import { RouterEffects } from ’./router.effects’;
import { ReportEffects } from ’./report.effects’;

export const effects: any[] = [UserEffects, RouterEffects, ReportEffects];

export * from ’./user.effects’;
export * from ’./router.effects’;
export * from ’./report.effects’;
報告篇 - Selector
直接修改 src/app/store/selectors/selectors.ts

import { createSelector } from ’reselect’;

import * as fromReducer from ’../reducers’;
import * as user from ’../reducers/user.reducers’;
import * as router from ’../reducers/router.reducers’;
import * as report from ’../reducers/report.reducers’;

import { Report } from ’../../models’;

// for selector
export const getUserState = (state: fromReducer.State) => state.user;                        // point to users state subtree
export const getIsLogin = createSelector(getUserState, user.getIsLogin);
export const getCurrentUser = createSelector(getUserState, user.getCurrentUser);

export const getRouterState = (state: fromReducer.State) => state.router;

export const getReportState = (state: fromReducer.State) => state.report;
export const getReports = createSelector(getReportState, report.getReports);

// join selector
export const getSelectedReport = createSelector(getRouterState, getReportState, (router, reportState): Report => {
return router.state && reportState.reports.filter(report => report.id

=== +router.state.params.rptId)[0];
})
分別從 State 抓到狀態樹的根 (getUserState, getRouterState, getReportState)
export 原來 reducer 下的 selector
getSelectedReport 比較特別,它需要用到兩種狀態,一是路由的 params指到的 rptId,一是整個報告的陣列,利用陣列的 .filter() 回傳這個 rptId 的報告,當中的一些檢查(那份報告存不存在?)先省略
下次我們就可以完成其他的部分(報告預載,修改報告服務,修改元件)

转载请注明:XAMPP中文组官网 » ngrx/store 之報告篇