首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular2和Redux :获取组件中的状态

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

Stack Overflow用户
提问于 2016-11-25 01:11:30
回答 1查看 3.9K关注 0票数 2

我需要访问组件内部的状态。大多数示例展示了如何使用@select和异步管道而不是直接在组件中使用模板内部的状态。所需的状态不应该随着时间的变化而改变。

我认为有三种解决办法:

1/使用getState()

代码语言:javascript
复制
constructor(private ngRedux: NgRedux) { }
ngOnInit() {
    this.prop = this.ngRedux.getState().prop;
    // Do what I need with "this.prop"
}

2/将此getter移动到Action服务

代码语言:javascript
复制
getProp() {
    return this.ngRedux.getState().prop;
}

3/订阅@select()属性

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

最好的方法是什么?

Thx

EN

回答 1

Stack Overflow用户

发布于 2017-06-19 06:02:48

这可能没有正确或错误的答案,但刚刚添加了一个角度应用程序的Redux,以下是我的想法。

ngRedux.getState()返回快照,而@select()则设置一个管道,在状态片段每次更改时进行响应。

使用Redux的主要原因之一是降低共享状态的复杂性,在这种情况下,我们希望使用@select来响应由其他组件引起的更改。

上面的示例3有问题。

首先,我们不能确定在ngOnInit()代码的其余部分执行之前订阅是否会完成,所以当我们不希望它被初始化时,this.property可能是未初始化的。

其次,我们想要快照,在这种情况下使用getState(),还是需要一个管道,在这种情况下,将后续代码移动到订阅中:

代码语言:javascript
复制
@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值,例如

代码语言:javascript
复制
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
  }
}

警卫可用于:

代码语言:javascript
复制
ngOnInit() {
  config$
    .filter(data => !!data)
    .subscribe(config => {
      this.color = config.color;
  }
}

或确保initialState初始化所有对象级别:

代码语言:javascript
复制
export const initialState: IAppState = { config: {} }

管道连续执行

如果需要在更新前查看现有状态,则订阅将不断启动。注意,订阅和分派之间的连接可能是微妙的(子状态变化,或嵌套方法的分离):

代码语言:javascript
复制
@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)中取消订阅。如果不执行此步骤,则组件消失后订阅将继续进行。参考文献:Subscription

代码语言:javascript
复制
@select() myData$: IMyData;
private myDataSub;

myMethod() {
  this.myDataSub = this.myData$.subscribe(myData => {
    // Do something with myData
  }
}
ngOnDestroy() {
  this.myDataSub.unsubscribe();
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40796403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档