#javascript #angular #typescript #rxjs #observable
#javascript #угловой #машинописный текст #rxjs #наблюдаемый
Вопрос:
В моем приложении 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)
}
Моя цель состоит в том, чтобы в моем редукторе я не просто отправлял в хранилище (BehaviourSubject) новые данные, но я хочу, чтобы он добавлял их к существующим (я не хочу, чтобы новое значение заменяло существующее) :
В результате это будет выглядеть так :
данные для отправки в BehaviourSubject (массив) = существующие данные (массив объектов) новые данные (объект)
мой редуктор выглядит так, и я попробовал это :
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()
, потому что я не могу справиться с отменой подписки, а метод пользовательского щелчка будет повторяющимся (возможно, subscribe будет каждый раз открывать новую подписку)
Я ищу лучший способ сделать это правильно (возможно, изменить BehaviouSubject)
Предложения ??
Комментарии:
1. вероятно, вам следует использовать ngrx для этого, а затем просто получить состояние
data: [...state.data, ...newData]
2. хочу установить эквивалент ngrx с помощью rxjs и behaviourSubjects @Jean-XavierRaynaud
3. в этом случае вам нужно использовать .value объекта BehaviorSubject, под капотом ngrx использует BehaviorSubjects для создания состояния и использования .value, когда вам нужно получить к нему доступ.
4. Могу я спросить, почему вы проходите через весь процесс, в основном повторно внедряя логику ngrx, не используя ее?
5. существует разница между .value и getVlaue() BehaviourSubject ?
Ответ №1:
Как объясняется в некоторых комментариях к вашему вопросу, для этого существуют библиотеки, и вам, вероятно, следует использовать их вместо изобретения колеса.
Тем не менее, давайте предположим, что это для целей обучения, и сделаем это в любом случае.
Я бы рекомендовал использовать реактивное программирование и создавать все в виде потоков. Затем создайте супертонкий слой в сервис, чтобы обернуть это, чтобы вы могли предоставить его посредством внедрения зависимостей.
Для реактивного бита у меня просто был бы объект, которому я бы передавал действия. Исходя из этого, у меня был бы поток, поддерживающий состояние. Это будет выглядеть следующим образом:
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)
}
}
Комментарии:
1. цель состоит в том, чтобы объединить данные для передачи как next (data_to_pass = старое значение новое значение)
2. Я не понимаю. Реактивное программирование означает, что действия и редукторы должны быть чистыми функциями, а не потоками. Селекторы — это потоки, но это выходит за рамки.
3. Реактивное программирование ничего не значит о действиях и редукторах. Действия — это простой объект, который можно сериализовать, редукторы — это чистые функции, которые принимают текущее состояние и на основе действия возвращают новое состояние (это эквивалент сканирования выше). Селекторы не являются потоками. Селекторы — это чистые функции, которым вы передаете другие селекторы для получения другого вывода. Этот вывод может быть вычислен на основе данных, поступающих из хранилища, или просто других данных, основанных на других селекторах.
4. Но реактивное программирование — это всего лишь потоки. Это не связано с какими-либо проблемами управления состоянием, такими как действия, редукторы или селекторы.