有可能沒有正確或錯誤答案,但剛剛加入Redux的一個角的應用程序,這是我的想法。
ngRedux.getState()
返回一個快照,而@select()
設置一個管道,每當狀態片段發生變化時都會響應。
一個使用終極版的主要原因是爲了降低複雜性與共享狀態,在這種情況下,我們要使用@select
,以引起其它組件的變化做出反應。
上面的例3是有問題的。
首先,我們無法確定在執行ngOnInit()
代碼的其餘部分之前預訂會完成,因此this.property
可能會在我們預料不到時被初始化。
其次,做我們想要的快照,在這種情況下使用getState()
,還是我們需要一個管道,在這種情況下,移動內部的後續代碼訂閱:
@select('stateProp') stateProp$;
property: string;
constructor(private ngRedux: NgRedux) { }
ngOnInit() {
stateProp$.subscribe(state => {
this.property = state;
// Do what I need with "this.property"
})
}
同樣可以說,當我們在其他方法中使用this.property
。
似乎我this.property
和stateProp$
指的是相同的狀態,所以有一個或另一個,但不是兩個。
除了限制代碼的形狀,我發現@select()
還有其他一些問題。
流水線在狀態被初始化之前執行。
根據狀態如何初始化,我們可能會通過管道接收undefined
值,摹
export interface IAppState {
config?: any;
}
export const initialState: IAppState = {}
@select() config$: any;
ngOnInit() {
config$.subscribe(config => {
this.color = config.color; // Error: Cannot read property 'color' of undefined
// May happen if config is obtained async
}
}
的防護,可以用:
ngOnInit() {
config$
.filter(data => !!data)
.subscribe(config => {
this.color = config.color;
}
}
或確保初始化狀態初始化所有對象級別:如果你需要看
export const initialState: IAppState = { config: {} }
管道連續執行
現有狀態在更新之前,訂閱將不斷激活。注意,訂閱和調度之間的連接可能是微妙(子狀態的變化,或通過分離嵌套方法):
@select() myDataList$: IDataArray;
myMethod() {
this.myDataList$.subscribe(myDataList => {
// Check something on myDataList
console.log('I will continuously loop');
this.addDataMethod();
}
}
addDataMethod() {
ngRedux.dispatch({type: addSomeDataAction, payload: myData});
}
使用ngRedux.getState()
將是優選的接入方法,或用.take(1)
限制訂閱。
清理訂閱
訂閱的角度目前需要退訂在ngOnDestroy()
如果不與.take(n)
或類似的操作完成。如果沒有這一步,訂閱將在組件消失後繼續。編號:Angular/RxJs When should I unsubscribe from `Subscription`
@select() myData$: IMyData;
private myDataSub;
myMethod() {
this.myDataSub = this.myData$.subscribe(myData => {
// Do something with myData
}
}
ngOnDestroy() {
this.myDataSub.unsubscribe();
}