3

我对 NGXS Store 和@Selector()状态类层次结构中 memoized 的使用有疑问。

下面描述的问题的推荐方法是什么?NGXS Store 文档没有提供这方面的指南/建议。

鉴于此示例状态设置,


export interface BaseModel { data: string[]; }

// base class not a state!
export class BaseState {
  @Selector()
  static dataSelect(state: BaseModel) { return state.data; }

  // ...
}

export interface DerivedModel extends BaseModel {}

@State<DerivedModel>({ name: 'derived'; })
export class DerivedState extends BaseState {
  // ...
}   

export interface UsingModel { thing: number; }

@State<UsingModel>({ name: 'using'; })
export class UsingState implements NgxsOnInit {

  constructor(private _store: Store) {}

  ngxsOnInit(ctx: StateContext<UsingModel>) {
    // have this state update when derived state changes
    this._store.select(DerivedState.dataSelect).subscribe(data => console.log(data));
  }

  // ...
}

当让这段代码运行时,它会打印出来,undefined因为方法的state参数dataSelect(...)不会被设置。

我追踪到BaseState不是 NGXS 状态的原因,因此缺少一个内部NGXS_META 属性,这反过来又导致了undefined争论。添加BaseState到选择器(例如@Selector([BaseState]))以强制仍然包含状态也不会产生预期的效果,因为现在 NGXS 无法导航到匹配的状态切片。

@Selector(...)我找到了两种方法来使这项工作按需要进行: 1.在每个派生状态实现中复制该方法。这虽然违背了最初设计状态类层次结构的原因。@DerivedSelector(...)2.根据标准装饰器使用类似的东西,但会为每个遇到的派生状态类动态创建选择器。

谢谢你。

4

1 回答 1

1

据我所知,这不能使用@Selector注释来实现,而是使用createSelector().

export class BaseState {
  static dataSelect() {
    return createSelector(
      [this],
      (state: BaseModel) => {
        return state.data;
      }
    );
  }

  //...
}

如果您像这样更改基本状态,您的代码将起作用。有关详细信息,请参阅NGXS 文档

于 2020-03-08T04:49:13.910 回答