gpt4 book ai didi

angular - 在 NGRX 中的任何 Action 调度后执行效果

转载 作者:行者123 更新时间:2023-12-05 06:24:08 24 4
gpt4 key购买 nike

我正在使用 NGRX 和 Angular 7。

我有一个仅用于用户设置(用户首选项)的商店

这是一个简短的版本=>

import { Action } from '@ngrx/store';
import * as featureModels from './models';

export enum ActionTypes {
SetSettings = '[SETTINGS] Set Settings',
SetNavigationSettings = '[SETTINGS] Set Navigation Settings',
}

export class SetNavigationSettings implements Action {
public readonly type = ActionTypes.SetNavigationSettings;
constructor(public payload: {settings: Partial<featureModels.INavigationSettings>}) {}
}

export class SetSettings implements Action {
public readonly type = ActionTypes.SetSettings;
constructor(public payload: {settings: featureModels.ISettings}) {}
}

export type Actions = SetNavigationSettings |
SetSettings;

任何设置更改后,我想执行一个效果,将当前设置存储在本地存储中:

目前在我的效果中,我只是使用这样的选择器,它会在任何状态更改后触发(所以它工作正常)=>

export class SettingsEffects {

constructor(
private actions$: Actions,
private dataService: SettingsDataService,
private localStorageService: LocalStorageService,
private store$: Store<IAppState>
) {
this.store$.pipe(select(featureSelector.selectSettingsState)).subscribe((settings) => {
//save
});
}

@Effect()
init$ = this.actions$.pipe(
ofType(ROOT_EFFECTS_INIT),
switchMap(action => {
const settings = this.localStorageService.retrieve('settings');
console.log(settings)
if (settings) {
return of(new featureActions.SetSettings({settings}));
} else {
return EMPTY;
}
})
);

但是,这将在初始化时执行,所以在我的 INIT 效果之前,它总是会用存储初始状态覆盖 localStorage 值。这将使我的 Init 效果仅从本地存储中检索初始状态。

我可以将商店选择放在 Init Effect 中(而且效果很好)

但我想知道是否有一种不使用选择器/订阅而只使用效果的方法。这样每次用户触发 Action 时,它都会保存。

最佳答案

official NgRx docs 中所述,您可以考虑使用 MetaReducers。

Developers can think of meta-reducers as hooks into the action->reducer pipeline. Meta-reducers allow developers to pre-process actions before normal reducers are invoked.

使用 meta-reducer,您可以在每次执行操作时执行代码。如上所述,此代码在调用普通 reducer 之前执行。在您的情况下,要存储新状态(在执行当前操作之后),您应该在调用 reducer(state, action) 之后使用返回的状态。

export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
return function (state, action) {
const nextState = reducer(state, action);

console.log('log action', action);
console.log('log state', state);
console.log('log next state', nextState);

// store nextState in local storage
localStorage.setItem('state', JSON.stringify(nextState));

return nextState;
};
}

我准备了一个 Stackblitz demo来说明这个答案。

但是,我可以通过与您分享个人观点来建议您另一种选择吗?事实上,每个 Action 都会调用 meta-reducer。这可能会导致大量不需要的存储调用。

在这种情况下,我宁愿在每个相关效果中调用另一个特定操作来明确请求状态保存。但很明显,缺点是一些重复代码,并且有错过电话的风险。

关于angular - 在 NGRX 中的任何 Action 调度后执行效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57849955/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com