Angular2和Redux:获取组件中的状态

时间:2016-11-25 01:11:30

标签: angular redux

我需要访问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

1 个答案:

答案 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.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;
  }
}

或确保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();
}