我需要访问Component内的状态。大多数示例显示如何使用@select和async管道消耗模板内的状态,但不直接在Component中使用。所需的状态不应该在时间上改变。
我看到3个解决方案:
1 /使用getState()
constructor(private ngRedux: NgRedux) { }
ngOnInit() {
this.prop = this.ngRedux.getState().prop;
// Do what I need with "this.prop"
}
2 /将此getter移至Action Creator服务
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 :(得分:3)
对此可能没有正确或错误的答案,但刚刚将Redux添加到Angular应用程序中,这是我的想法。
ngRedux.getState()
返回快照,而@select()
设置一个管道,每次状态片段更改时都会响应。
使用Redux的一个主要原因是通过共享状态降低复杂性,在这种情况下,我们希望使用@select
来响应其他组件引起的更改。 / p>
上述示例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;
}
}
或确保initialState初始化所有对象级别:
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();
}