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

Store 加入 select

XAMPP下载 admin 775浏览 0评论
 Store 加入 select
我們的 Store 內部大致完成,但是對於客戶 (Subscriber),我們還少了介面,在 ngrx/store 裡,給客戶的介面是用 store.select(),.select() 最主要的目的是提供 Subscriber 它所要的狀態,而不是整個狀態樹,它是一個 Observable,客戶 subscribe() 後會被 push 新的狀態。

加入 Select
我們知道 Store 是一個 BehaviorSubject,它隨時會紀錄最新的狀態樹,而狀態樹用 key 來做分類,所以做 select() 其實很簡單,只要用一個 .map() Operator如下:

class Store extends Rx.BehaviorSubject<Action> {
// 省略 …
select(key:string) {
return this.map(state=> state[key]);
}
}
// 省略 …
// add subscriber
const sub1 = store.select(‘login’)
.subscribe(s => console.log(‘login status => ‘, s));

const sub2 = store.select(‘messages’)
.subscribe(s => console.log(‘messages => ‘, s));

// start dispatch action about login
store.dispatch({type: ‘LOGIN’});
store.dispatch({type: ‘LOGOUT’});
store.dispatch({type: ‘LOGIN’});

// start dispatch about messages
store.dispatch({type: ‘ADD_MESSAGE’, payload: {id: 1, msg: ‘First Message’}});
store.dispatch({type: ‘ADD_MESSAGE’, payload: {id: 2, msg: ‘Second Message’}});
store.dispatch({type: ‘REMOVE_MESSAGE’, payload: 1});
這裡假設 sub1只對 login 有興趣,而 sub2 只對 messages 有興趣,但是我們來看一下輸出

QQ截图20181009163916
 這種做法的話,每次 store dispatch 一個 Action 時,sub1 跟 sub2 都會得到一個值,而對於 sub2 而言,login 有關的 Action 並不會帶給 messages 新的值, 所以一剛開始時,sub2 一直收到 [] 的狀態,這不是它想要的。

在 Observable 中有一個 Operator .distinctUntilChange(),它會根據新的 .next() 做過濾,如果值不變,它會將它過濾掉,不會丟給 Subscriber。

Select with distinctUntiChange
我們加入 .distinctUntilChange() 在 .select()

class Store extends Rx.BehaviorSubject<Action> {
// 省略 …
select(key:string) {
return this.map(state=> state[key])
.distinctUntilChanged();
}
}
結果如下

QQ截图20181009163924
 果然清爽許多,sub1 跟 sub2 都會得到它們想要的結果。

完整程式
interface Action {
type: string;
payload?: any
}

class Dispatcher extends Rx.Subject<Action> {
dispatch(act) {
this.next(act);
}
}

class Store extends Rx.BehaviorSubject<Action> {
constructor(private dispatcher, private reducer, initialState) {
super(initialState);
this.dispatcher
.do((v) => { /*console.log(‘do some effect for’, v.type) */ })
.scan((s, v) => this.reducer(s, v), initialState)
.subscribe(state => {
super.next(state);  // new state, push to subscriber
});
}
dispatch(act) {          // delegate to dispatcher
this.dispatcher.dispatch(act);
}
// override next to allow store subscribe action$
next(act) {
this.dispatcher.dispatch(act);
}
select(key:string) {
return this.map(state=> state[key])
.distinctUntilChanged();
}
}

const login = (state = false, action) => {
switch (action.type) {
case ‘LOGIN’:
return true;
case ‘LOGOUT’:
return false;
default:
return state;
}
}

const messages = (state = [], action) => {
switch (action.type) {
case ‘ADD_MESSAGE’:
return […state, action.payload];
case ‘REMOVE_MESSAGE’:
return state.filter(msg => msg.id

!= action.payload);
default:
return state;
}
}

const myReducer = {login, messages};       // object of two reducer functions
const combineReducer = reducers => (state, action) => {
return Object.keys(reducers).reduce((nextState, key) => {
nextState[key]=reducers[key](state[key], action);
//console.log(‘nextState is ‘, nextState);
return nextState;
}, {})
}

const rootReducer = combineReducer(myReducer);

// instanciate new store with initialstate
const initialState = {login: false, messages: []};
const dispatcher = new Dispatcher();
const store = new Store(dispatcher, rootReducer, initialState);

// add subscriber
const sub1 = store.select(‘login’)
.subscribe(s => console.log(‘login status => ‘, s));

const sub2 = store.select(‘messages’)
.subscribe(s => console.log(‘messages => ‘, s));

// start dispatch action about login
store.dispatch({type: ‘LOGIN’});
store.dispatch({type: ‘LOGOUT’});
store.dispatch({type: ‘LOGIN’});

// start dispatch about messages
store.dispatch({type: ‘ADD_MESSAGE’, payload: {id: 1, msg: ‘First Message’}});
store.dispatch({type: ‘ADD_MESSAGE’, payload: {id: 2, msg: ‘Second Message’}});
store.dispatch({type: ‘REMOVE_MESSAGE’, payload: 1});

codepen

至此,我們已經將 Observable 跟 store 介紹差不多了, ngrx/store 有三大主軸, Angular (ng), Observable (rx) 跟 Store (flux),接下來我們要進入 Angular 主題來應用 ngrx/store。

转载请注明:XAMPP中文组官网 » Store 加入 select

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