在我的Angular应用程序中,我正在使用BehaviourSubject设置状态管理逻辑
因此,我在存储文件中保存了以下内容:
myStoreData = new BehaviourSubject([])
在我的操作文件中,我有这个:
export const SAVE_DATA_IN_CONTEXT = '[User] Save user the incoming data';
因此,在组件中,当需要时,要调用的方法是:
click(newData){
this.reducerService('SAVE_DATA_IN_CONTEXT' , newData)
}
我的目的是,在我的reductor中,我不会只是将新数据发送到存储(behaviourSubject(,而是希望它将其与现有数据相加(我不希望新值取代现有值(:
结果会是这样的:
要发送到BehaviourSubject的数据(数组(=现有数据(对象数组(+新数据<strong](对象(>
我的减速器是这样的,我试过了:
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)
}
}