In angular (v5) how do I listen to my apps Redux state object changing?

白昼怎懂夜的黑 提交于 2019-12-30 12:13:30

问题


I need to know how to create a listener e.g. I want to subscribe to the AppState changing.

Below is my current very basic service. I have a dispatch action on the view which increments the counter.

Once the counter changes value I'd like to detect this in other parts of my website e.g. the global header for example.

I'm using ng2-Redux with angular version 5.

Redux service:

export interface IAppState {
    counter: number;
}

export const INITIAL_APP_STATE: IAppState = {
    counter: 0
};

export function appReducer(state: IAppState, action: any): IAppState {
    switch (action.type) {
        case 'INCREMENT':
        return {
            counter: state.counter + action.payload
        };
    }
    return state;
}

回答1:


angular-redux offers a very convenient way of selecting slices of your store with the @select() decorator.

Let's say your IAppState would be:

export interface IAppState {
  counter: number;
  auth: {token: string}; 
}

Then you can select the parts of your state like this:

// variable name is equal to state property + $
@select() counter$: Observable<number>;
@select() auth$: Observable<{token: string}>;

// path to store slice
@select(['auth', 'token']) token$: Observable<string>;

For further information, have a look at the select docs.




回答2:


I declare the actions in a file

// action.ts 
export const FILTER_ROLES = "FILTER_ROLES"

// this action will be handled in the effect
export class FilterRoles implements Action {
  readonly type = FILTER_ROLES
  constructor(public query: any) { }
}

export const FILTERED_ROLES = "FILTERED_ROLES"

// this one will modify the reducer 
export class FilteredRoles implements Action {
  readonly type = FILTERED_ROLES
  constructor(public values: Array<any>, public total: number) { }
}

the effects file will look like this, (effects will call the backend)

@Injectable()
export class RoleEffects {
@Effect() filter_roles = this.actions$
        .ofType(FILTER_ROLES)
        .flatMap((action: FilterRoles) => {
            return
                backendCall() 
                .mergeMap(({ values, total }) => {
                    return [
                        new FilteredRoles(values, total)
                    ]
                }).catch((err: Error) => { console.log("sss") })
}

the reducer will modify the current state of your store

export function RoleReducer(state: Roles = { values: [], total: 0 }, action: RoleActions) {

    switch (action.type) {
        case FILTERED_ROLES:
            return Object.assign({}, state, { values: action.values, total: action.total })
        default:
            return state
    }
}

In my module declaration you should declare both effects and reducer actions

const EffectModules = [
    EffectsModule.run(RoleEffects)
....
....
]

in the imports of my module I will declare all the reducer and effects

@NgModule({
    imports: [
StoreModule.provideStore({roles: RoleReducer,
... // all the other reducers
}),
...EffectModules,
]
})

I hope this code will help you



来源:https://stackoverflow.com/questions/48950721/in-angular-v5-how-do-i-listen-to-my-apps-redux-state-object-changing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!