NGXS Тайм-аут неактивности - PullRequest
1 голос
/ 27 января 2020

В Angular проекте. Я новичок в NGXS и пытаюсь преобразовать эффект NGRX, который наблюдал за всеми действиями, и если действие не было действием выхода из системы, оно сбрасывало таймер. Если время таймера истекло до другого действия, он автоматически выполняет выход пользователя из системы. Я не уверен, как добиться этого в NGXS. Вот мой эффект NGRX:

@Effect()
extendApplicationTimeout$: Observable<any> = this.actions$.pipe(
    switchMap((action: Action) => {
        if (action.type !== 'LogoutUser'){
            return timer(this.APPLICATION_TIMEOUT_TIME)
        }
    }),
    map(() => new LogoutUser())
);

Ответы [ 2 ]

0 голосов
/ 28 января 2020

Альтернативой может быть прослушивание потока действий NGXS для управления этим таймером на верхнем уровне.

Вы можете создать инъекционную службу, которую вы загружаете в app.module providers через APP_INITIALIZER токен.

@Injectable({provideIn: 'root'})
export class AppTimeoutHandler { 
    constructor(private actions$: Actions, private store: Store) {
  ...// subscribe to `actions$` and then reset timer
  ...// when timer expires, store.dispatch(.. new LogoutAction())

  }
}
0 голосов
/ 27 января 2020

Вы можете использовать Meta Reducer: https://www.ngxs.io/advanced/meta-reducer

import { getActionTypeFromInstance } from '@ngxs/store';

export function extendApplicationPlugin(state, action, next) {
  // Use the get action type helper to determine the type
  if (getActionTypeFromInstance(action) !== LogoutUser.type) {
    // do timer stuff...
  }

  // return the next function with the next state
  return next(state, action);
}

Вы бы подключили его так:

import { NgModule } from '@angular/core';
import { NGXS_PLUGINS } from '@ngxs/store';

@NgModule({
  imports: [NgxsModule.forRoot([])],
  providers: [
    {
      provide: NGXS_PLUGINS,
      useValue: extendApplicationPlugin,
      multi: true
    }
  ]
})
export class AppModule {}

У вас не будет сделать это таким образом. Вы также можете использовать getActionTypeFromInstance(action) в своем собственном плагине.

Если вам нужно отправить событие, вам нужно будет использовать useFactory с deps и ввести Store или использовать инжектор, чтобы получить ссылка на Store.

Не проверял это, и я не знаю, будет ли это работать, надеюсь, это подтолкнет вас в правильном направлении:

import { NgModule } from '@angular/core';
import { NGXS_PLUGINS, Store } from '@ngxs/store';

@NgModule({
  imports: [NgxsModule.forRoot([])],
  providers: [
    {
        provide: NGXS_PLUGINS,
        useFactory: extendApplicationPlugin,
        deps: [Store],
        multi: true,
    }
  ]
})
export class AppModule {}

Реализация

import { getActionTypeFromInstance, Store } from '@ngxs/store';


export function extendApplicationPlugin(store: Store) {
  return function extendApplicationPlugin(state, action, next) {
    // Use the get action type helper to determine the type
    if (getActionTypeFromInstance(action) !== LogoutUser.type) {
      // do timer stuff...
      // store.dispatch()
    }

    // return the next function with the next state
    return next(state, action);
  }
}
...