在ngrx上创建非memoized选择器

时间:2018-06-19 03:42:06

标签: angular ngrx ngrx-store

是否可以在ngrx上创建一个非memoized选择器?

我有一个非常小的选择器来检查商店中的值是否大于Date.now()。

export const selectAuthState = createFeatureSelector<AuthState>('auth');
export const hasTimeout = createSelector(
  selectAuthState,
  state => state.timeout < Date.now()
);

正如预期的那样,此选择器没有用,因为除非我更改timeout的值,否则不会重新计算它。有没有办法使选择器非memoized,以便每次访问其值时重新计算?

我目前的解决方案是创建一个选择器工厂并每次都使用它,但我认为这不是最好的解决方案:

export const hasTimeoutFactory = () => createSelector(
  selectAuthStatusState,
  state => state.timeout < Date.now()
);

另一种解决方案是做类似

的事情
export const didTimeout = pipe(
  select(getTimeout), // using memoized value
  map(val => val < Date.now())
);

然后导入此管道。

2 个答案:

答案 0 :(得分:0)

选择器具有release方法来重置备忘录,我想这就是您要使用的。

这将转换为以下代码:

this.timeout = this.store.pipe(select(hasTimeout));
hasTimeout.release();

Docs

答案 1 :(得分:0)

我遇到了类似的问题,并且执行了以下操作-我很确定NgRx架构是错误的,但是它可以满足我的要求。

export const selectAuthorizationDetails = createSelector(selectAuthorizationState, 
    (state: AuthorizationState, store: Store<AuthorizationState>) => store,
    (state: AuthorizationState) => new Date(),     // Force the selector memoization to fail which is probably the wrong thing to do
      (state, store, timeNow) => {
        if (state.lastUpdated != null) {
            let diffMs = timeNow.getTime() - state.lastUpdated.getTime()
            if (diffMs > 300000) {
                store.dispatch(refreshAuthorization());
                return null;
            }
            return state.authorizationDetails;
        }
        return null;
      }
  );

在存储区中,我的授权详细信息存储了上次更新时间,等等。每次调用时,它都会测试它们是否已过期。如果我使用备忘录,则它将不起作用,则必须在每次调用时释放选择器,这意味着我可能需要将选择器隐藏在门面后面。

在AuthGuard中使用选择器时,我只是对null进行过滤,这样我就可以始终获取最新版本,但可以将结果缓存预定的时间(在此示例中为5分钟)