Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RxJs:如何将数据附加到行为主体(用新值表示最后一个值)_Javascript_Angular_Typescript_Rxjs_Observable - Fatal编程技术网

Javascript RxJs:如何将数据附加到行为主体(用新值表示最后一个值)

Javascript RxJs:如何将数据附加到行为主体(用新值表示最后一个值),javascript,angular,typescript,rxjs,observable,Javascript,Angular,Typescript,Rxjs,Observable,在我的Angular应用程序中,我正在使用行为主题设置状态管理逻辑 因此,我在我的存储中保存了以下文件: myStoreData = new BehaviourSubject([]) 在我的操作文件中,我发现: export const SAVE_DATA_IN_CONTEXT = '[User] Save user the incoming data'; 因此,在组件中,当需要时,要调用的方法如下: click(newData){ this.reducerService('SAVE_D

在我的Angular应用程序中,我正在使用行为主题设置状态管理逻辑

因此,我在我的存储中保存了以下文件:

myStoreData = new BehaviourSubject([])
在我的操作文件中,我发现:

export const SAVE_DATA_IN_CONTEXT = '[User] Save user the incoming data';
因此,在组件中,当需要时,要调用的方法如下:

click(newData){
  this.reducerService('SAVE_DATA_IN_CONTEXT' , newData)
}
我的目的是,在我的reducer中,我不只是将新数据发送到存储(行为主体),而是希望它将其附加到现有数据中(我不希望新值替换现有值):

因此,它看起来是这样的:

要发送到行为主题(数组)=现有的数据 数据(对象数组)+新数据(对象)

我的减速机看起来像这样,我试过:

public dispatchAction(actionTag: string, newDataPayload: any | null): void {
    
    switch (actionTag) {
      case ActionsTags.SAVE_DATA_IN_CONTEXT :
        const newDataToSet = [...Stores.myStoreData.getValue() , ...newDataPayload ];
        Stores.myStoreData.next(newDataPayload);
        break;

}
因为我确信方法getValue()是一种糟糕的做法,我不会路过
Stores.myStoreData.subscribe()
,因为我无法处理取消订阅,而且用户单击方法会重复(可能订阅每次都会打开一个新订阅)

我正在寻找一种更好的方式来正确地完成它(可能会改变行为主体)


建议???

正如您的问题下的一些评论中所解释的,这里有一些库,您可能应该使用它们,而不是重新发明轮子

这就是说,让我们假设这是为了学习的目的,无论如何都要这样做

我建议采用反应式编程,并将所有内容构建为流。然后在服务中创建一个超小的层来包装它,这样您就可以通过依赖注入来提供它

对于被动部分,我只需要一个主题,我会将动作传递给它。基于此,我将有一个流来维护状态。如下所示:

const action$ = new Subject();

const state$ = action$.pipe(
  scan((state, action) => {
    switch (action.type) {
      case 'some_action':
        // todo: return a new state
      default:
        state;
    }
  })
);
然后,如果您想将其提供到服务中,您只需执行以下操作:

@Injectable()
export class Store {
  private action$ = new Subject();

  public state$ = action$.pipe(
    scan((state, action) => {
      switch (action.type) {
        case 'some_action':
          // todo: return a new state
        default:
          state;
      }
    }),
    shareReplay(1)
  );

  public dispatch(action): void {
    this.action$.next(action)
  }
}

您可能应该使用ngrx来实现这一点,只需获取一个状态,然后
data:[…state.data,…newData]
要将ngrx与rxjs和BehaviorSubjects@Jean Xavierraynaud设置为等价的。在这种情况下,您必须使用behaviorSubject的值,在幕后,ngrx使用行为主体创建状态,并在需要访问时使用.value。我可以问一下,为什么不使用ngrx逻辑就要经历基本上重新实现ngrx逻辑的整个过程吗?Behavior Subject的.value和getVlaue()之间存在差异?目的是将数据组合起来作为下一步传递(数据传递=旧值+新值)我不明白。反应式编程意味着动作和减缩器应该是纯函数,而不是流。选择器是流,但这超出了范围。反应式编程对动作和减缩器没有任何意义。动作是可以序列化的简单对象,减缩器是采用当前状态和基于一个操作返回一个新状态(这相当于上面的扫描).选择器不是流。选择器是纯粹的函数,您可以将其他选择器传递给它们以产生不同的输出。此输出可以根据来自存储区的数据或基于其他选择器的简单其他数据计算。但反应式编程只是关于流。它与任何状态管理问题(如操作、还原或还原)无关选择器。