2016-11-25 26 views
0

我需要訪問組件內部的狀態。大多數示例顯示如何使用@select和異步管道消耗模板內部的狀態,但不直接在組件中使用。所需的狀態在時間上不應該改變。Angular2和Redux:獲取組件中的狀態

我看到3種溶液:

1 /使用的getState()

constructor(private ngRedux: NgRedux) { } 
ngOnInit() { 
    this.prop = this.ngRedux.getState().prop; 
    // Do what I need with "this.prop" 
} 

2 /移動此吸氣成動作創建者服務

getProp() { 
    return this.ngRedux.getState().prop; 
} 

3 /訂閱@select()屬性

@select('stateProp') stateProp$; 
property: string; 
constructor(private ngRedux: NgRedux) { } 
ngOnInit() { 
    stateProp$.subscribe(state => this.property = state) 
    // Do what I need with "this.property" 
} 

執行該操作的最佳方式是什麼?

THX

回答

0

有可能沒有正確或錯誤答案,但剛剛加入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.propertystateProp$指的是相同的狀態,所以有一個或另一個,但不是兩個。

除了限制代碼的形狀,我發現@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(); 
} 
相關問題