如何在获取数据/订阅后发送操作

时间:2017-04-27 22:50:00

标签: angular ionic2 rxjs ngrx

获取订阅数据后,我想发送如下操作。 但订阅和发送都是异步执行的,没有链被强制下注。订阅和发送。也不可能在subscribe中描述dispatch,这样会导致无限循环。

当我从订阅中获取某些数据时,有什么更好的方式来发送操作?

我目前的代码是,

// MyApp.ts
ngOnInit() {
    this.store.subscribe(appState => {
        this.userId = ppState.currentUserId;
    )};

    this.store.dispatch(new LoadInitialData(this.userId);
    data$ = this.store.select('data');
}

我可能的解决方案就是实现@Effect()......

// MyApp.ts
ngOnInit() {
    this.store.dispatch(new LoadUserId());
}

//MyEffectService.ts
@Effect() loadUserId$ = this.actions$
    .ofType(LOAD_USER_ID)
    .withLatestFrom(this.store.select('userId')
    .map([any, userId] => userId)
    .map(userId => new LoadInitialData(userId));

3 个答案:

答案 0 :(得分:2)

this.store
  .map(appState => ppState.currentUserId)
  .do(userId => this.store.dispatch(new LoadInitialData(userId))
  .subscribe(userId => this.userId = userId);

答案 1 :(得分:0)

使用set Instant它应该在循环的最后发送事件

this.store.subscribe(appState => 
    setImmediate(() => {
        this.userId = ppState.currentUserId
        this.store.dispatch(new LoadInitialData(this.userId)
    })
))

答案 2 :(得分:0)

您提到的“可能”解决方案看起来不错。

这是使您的智能组件(或容器)简单,没有太多业务逻辑的一种好习惯。

这就是为什么,我建议您将操作重命名为“ Load”或“ InitView”,“ Open” ...以更好地匹配实际操作。 (此处是视图的初始化,或视图的打开...)。将来,您可以想象初始化组件时会做更多的事情(不仅仅是加载用户数据...)。您的组件内部代码将保持简单,只需分派一个动作。业务逻辑仍会影响您。

关于这一点,请看Mike Ryan的精彩会议:Good Action Hygiene with NgRx

然后,使用效果分配另一个动作(加载所需的数据...)听起来非常好。

示例(没有新的效果/动作创建者语法):

// MyApp.ts
ngOnInit() {
  this.store.dispatch(new Init());
}

// MyEffectService.ts
@Effect() 
init$ = this.actions$
  .ofType(Init)
  .withLatestFrom(this.store.select(selectors.getUserId)
  .map([any, userId] => userId)
  .map(userId => new LoadInitialData(userId));

PS:另一种好的做法是始终使用selector来检索状态的一部分。 (在上面的示例中,我使用了selectors.getUserId