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

ngrx/store 設定篇及會員篇之 Action, Reducer

XAMPP下载 admin 1402浏览 0评论

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 ngrx/store 設定篇及會員篇之 Action, Reducer
今天開始 今天完成ngrx/store 設定
第一步:安裝相關套件

npm install @ngrx/core @ngrx/store @ngrx/effects @ngrx/router-store @ngrx/store-devtools reselect –save
第二步:建立目錄
在 src/app 底下

mkdir store
cd store
touch index.ts
mkdir actions
mkdir effects
mkdir reducers
mkdir selectors
並各自建立一個 index.ts,完成後如下

.
├── actions
│   └── index.ts
├── effects
│   └── index.ts
├── index.ts
├── reducers
│   └── index.ts
└── selectors
└── index.ts
第三步:修改 src/app/store/index.ts
如下

export * from ‘./actions’;
export * from ‘./reducers’;
export * from ‘.lectors’;
export * from ‘./effects’;
先填一些東西讓 Compiler 不要抱怨
store/actions/index.ts

export const actions = ‘Actions’;
store/reducers/index.ts

export const reducers = ‘Reducers’;
store/effects/index.ts

export const effects = ‘Effects’;
storelectors/index.ts

export const selectors = ‘Selectors’;
第四步:修改 src/app/app.module.ts

//… 省略
// for ngrx/store
import { StoreModule } from ‘@ngrx/store’;
import { EffectsModule } from ‘@ngrx/effects’;
import { StoreDevtoolsModule } from ‘@ngrx/store-devtools’;
import { StoreRouterConnectingModule, RouterStateSerializer } from ‘@ngrx/router-store’;
import { environment } from ‘../environments/environment’;
import * as fromStore from ‘./store’;
//… 省略

@NgModule({
//…
imports: [
//…
HttpClientModule,
StoreModule.forRoot(fromStore.reducers),
EffectsModule.forRoot(fromStore.effects),
!environment.production ? StoreRouterConnectingModule : [],
!environment.production ? StoreDevtoolsModule.instrument({ maxAge: 50 }) : [],
//…
],
//…
我們用 index.ts 將所有 store 的東西包起來,在 StoreModule.forRoot() 跟 EffectsModule.forRoot() 傳進 fromStore.reducers 跟 fromStore.effects
加入 environment 環境變數,用來判別現在是 production mode 還是 development mode,我們只有在 development mode 才會打開 StoreDevtoolsModule 跟 StoreRouterConnectingModule
StoreDevtoolsModule 讓我們可以使用 Chrome Extensions Redux Devtools 來看 ngrx/store 的 Action 跟 State
第五步:安裝 Chrome Extensions Redux Devtools
到 Google Chrome 擴充功能,尋找 Redux

QQ截图20181011155534
安裝後,點擊它會出現

QQ截图20181011155539

 這是一個很強大的工具,官方文件,我們在開發時,會隨時用這個工具來除錯,可以看到現在我們的 store 跟 effects 已經初始化 (init),也可以看到 ROUTER_NAVIGATION會員篇 – Actions
我們習慣上先定義動作(Actions),動作在 ngrx/store 裡其實是一個很簡單的物件,它的類別 (Class)如下
第一步: 在 store/actions/ 下建立 Class 檔案,並建立 spec 檔案 (測試用)

ng generate class user.actions –spec
第二步:修改 store/actions/user.actions.ts

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

// define action types
export const LOGIN = ‘[user] LOGIN’;
export const LOGIN_SUCCESS = ‘[user]  LOGIN_SUCCESS’;
export const LOGIN_FAIL = ‘[user] LOGIN_FAIL’;

export const LOGOUT = ‘[user] LOGOUT’;
export const LOGOUT_SUCCESS = ‘[user] LOGOUT_SUCCESS’;
export const LOGOUT_FAIL = ‘[user] LOGOUT_FAIL’;

export const GETUSER = ‘[user] GETUSER’;
export const GETUSER_SUCCESS = ‘[user] GETUSER_SUCCESS’;
export const GETUSER_FAIL = ‘[user] GETUSER_FAIL’;

// define Actions class
export class LoginAction implements Action {
readonly type = LOGIN;
constructor(public payload: User) { }
}
export class LoginSuccessAction implements Action {
readonly type = LOGIN_SUCCESS;
constructor(public payload: string) { }
}
export class LoginFailAction implements Action {
readonly type = LOGIN_FAIL;
constructor(public payload: any) { }
}
export class LogoutAction implements Action {
readonly type = LOGOUT;
}
export class LogoutSuccessAction implements Action {
readonly type = LOGOUT_SUCCESS;
}
export class LogoutFailAction implements Action {
readonly type = LOGOUT_FAIL;
}
export class GetUserAction implements Action {
readonly type = GETUSER;
}
export class GetUserSuccessAction implements Action {
readonly type = GETUSER_SUCCESS;
constructor(public payload: string) { }         // username
}
export class GetUserFailAction implements Action {
readonly type = GETUSER_FAIL;
constructor(public payload: any) { }
}
export type UserActions
= LoginAction
| LoginSuccessAction
| LoginFailAction
| LogoutAction

     | LogoutSuccessAction
| LogoutFailAction
| GetUserAction
| GetUserSuccessAction
| GetUserFailAction;
先從 @ngrx/store 導入 Action 介面
定義常數,我們為了怕會跟其他模組的字串重複,習慣上在字串前加模組名稱,如 [user] LOGIN
定義類別,有些動作帶 payload,有些不帶,帶 payload 的類別在這裡定義它的型態
最後 export UserActions 型態 (type)
因為用類別定義,我們將來在使用動作時,會用 new LoginAction() 的方式來產生物件
第三步:修改 app/store/actions/index.ts//export const actions = ‘Actions’;  刪除
export * from ‘./user.actions’;
未來加新的動作檔案,只要在這裡做 export,這樣就定義好我們在會員模組用到的動作,基本上分為三類,Login, Logout 跟 GetUser

會員篇之 Reducer
第一步:建立檔案 src/app/store/reducers 下

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

import { ActionReducer, Action, ActionReducerMap } from ‘@ngrx/store’;
import * as actions from ‘../actions’;

export interface UsersState {
isLogin: boolean;
currentUser: string;
}

const initialState: UsersState = {
isLogin: false,
currentUser: ”
}

export function reducer(state: UsersState = initialState, action: actions.UserActions): UsersState {
switch (action.type) {
case actions.LOGOUT:
return initialState;
case actions.LOGIN_SUCCESS:
case actions.GETUSER_SUCCESS:
//return Object.assign({}, state, { currentUser: action.payload, isLogin: true });
return { …state, currentUser: action.payload, isLogin: true };
default:
return state
}
}
// for selector
export const getIsLogin = (state: UsersState) => state.isLogin;
export const getCurrentUser = (state: UsersState) => state.currentUser;
先將剛剛定義的動作導入,記得 Reducer 的作用是將目前的狀態,加入新的動作,產生新的狀態,而新的狀態產生都要 Immutable,可以回顧一下之前的 [ngrx/store-12] Store 加完整的 Reducer 跟 [ngrx/store-7] 純函數 (Pure Function) 以及 [ngrx/store-8] Javascript Mutable 跟 Immutable 資料型態
定義狀態,這裡的狀態包含了登入狀態(布林值)及使用者名稱 (字串)
定義初始狀態,記得 Store 其實是一個 BehaviorSubject ([ngrx/store-11] Store 架構加入最簡單的 Reducer),我們需要給一個初始值
定義 reducer 函數,這個函數是純函數,在登入成功以及從後端得到使用者名稱成功後,產生新的狀態,可以用 Object.assign({}, state, {currentUser: action.payload, isLogin: true}); 或者擴展語法 {…state, currentUser: action.payload, isLogin: true};
最後 export 對應的兩個狀態,都是函數物件(function objects),這個會傳給上層的 selector,來讓使用者(元件或服務)訂閱最新的狀態。
第三步:修改 app/store/reducers/indext.ts

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

export interface State {
user: user.UsersState
}
export const reducers: ActionReducerMap<State> = {
user: user.reducer
}
定義最上層的狀態樹,以後加新的狀態,只要在這裡加上去即可
定義 root reducer,同樣,要加新的 Reducer,只要加入這裡,就會在 app.module.ts 中註冊
我們用這種 index.ts 的方式讓將來要擴充 store 的時候比較方便,後面會陸續看到加入的 狀態跟reducer。
下次我們來完成會員篇的 Effects 跟 Selector,以及更新元件

 

转载请注明:XAMPP中文组官网 » ngrx/store 設定篇及會員篇之 Action, Reducer

您必须 登录 才能发表评论!