初始化状态中的属性后,如何执行动作/效果?

时间:2020-11-05 18:55:56

标签: angular typescript rxjs ngrx ngrx-entity

我为每个新的组件声明都有一个新的组件存储。在ngOnInit中,我需要在化简器的状态上设置三个属性的值。执行完该操作后,我需要调用另一个调度,该调度将触发从服务器加载数据的效果。

具体来说,效果加载的数据必须引用在state中初始化的前面三个状态属性。但是,当我在效果中设置一个断点时,数据为空,这表明我的调度调用尚未设置值。

我知道您应该订阅已保存到存储中的数据,然后对其做出反应。也许这就是我需要做的,但是我无法弄清楚如何以菊花链方式链接三个状态属性的分配,然后再调用调度来启动数据加载NgRx效果。这是我要执行的操作的伪代码。

从ngOnInit内部

this.store.dispatch(actions.set_foo({ value: "A"}))
this.store.dispatch(actions.set_bar({ value: "B"}))
this.store.dispatch(actions.set_baz({ value: "C"}))

//This will call an effect.  The effect needs the data stored in state.foo, state.bar and state.baz
//How do I change this call so that it waits/subscribes to the assignment of Foo, Bar & Baz?
this.store.dispatch(actions.load_data_from_server());

从被叫效果内部

loadData$ = createEffect(
  ()=>this.actions$.pipe(
    ofType(actions.load_data_from_server),

    //selectParameterData is a selector that returns a composite object of Foo/Bar/Baz. There might be a better way to do this, but this allowed me to get three state properties in one.
    withLatestFrom(this.store$.select(selectors.selectParameterData),
    mergeMap([action, data]=>
    
    ... Code that makes a data ball to the server, passing in values from Foo/Bar/Baz ...
        This the place where the data is uninitialized.   
  )
)

请注意,我可以重组所有这些代码,但是应该正确完成。我们的团队已决定我们需要将Angular应用程序迁移到NgRx,而这些正是我需要解决的问题,并建立了一个将应用程序的一部分迁移到NgRx的示例。感谢您的帮助。

这显然是一个问题,如何在状态上设置多个属性,并且只有在分配了这些属性之后,才从服务器加载数据,并在我的reducer状态对象上引用这些属性?

1 个答案:

答案 0 :(得分:1)

您可以像这样链接动作处理程序:

从ngOnInit内部

this.store.dispatch(actions.set_all({ a: "A", b: "B", c: "C"} ));

从被叫效果内部

setAll$ = createEffect(
  () =>  this.actions$.pipe(
      ofType(actions.set_all),
      concatMap(t => {
         return [
            actions.set_foo({ value: t.a} ),
            actions.set_bar({ value: t.b} ),
            actions.set_baz({ value: t.c} ),
            actions.load_data_from_server
         ];
      })
)
loadData$ = createEffect(
  ()=>this.actions$.pipe(
    ofType(actions.load_data_from_server),

    //selectParameterData is a selector that returns a composite object of Foo/Bar/Baz. There might be a better way to do this, but this allowed me to get three state properties in one.
    withLatestFrom(this.store$.select(selectors.selectParameterData),
    mergeMap([action, data]=>
    
    ... Code that makes a data ball to the server, passing in values from Foo/Bar/Baz ...
        data is now initialized.   
  )
)

替代解决方案

或者使用带有setTimeout的异步调度程序来调度调度,这将在事件循环的下一个周期触发最后的调度。警告:这将再次触发更改检测(与之前的解决方案相比)。

this.store.dispatch(actions.set_foo({ value: "A"} ))
this.store.dispatch(actions.set_bar({ value: "B"}))
this.store.dispatch(actions.set_baz( { value: "C" }))
setTimeout(() => {
    this.store.dispatch(actions.load_data_from_server());
});