选择器何时执行? ngxs

时间:2019-02-22 06:18:14

标签: ngxs

实时演示https://stackblitz.com/edit/angular-vw78jf

我的ngxs状态下有ToppingsStateModel

export interface ToppingsStateModel {
  entities: { [ id: number ]: Topping };
  selectedToppings: number[];
}

一个动作更改了我的实体列表,另一个动作更改了selectedToppings。 在products.component中,我从选择器中获得浇头列表

export class ToppingsState {
  constructor(private toppingsService: ToppingsService) {
  }

  @Selector()
  static entities(state: ToppingsStateModel) {
    console.log('getEntities', state.entities);
    return state.entities;
  }

  @Selector([ToppingsState.entities])
  static toppings(state: ToppingsStateModel, entities: {[id: number]: Topping}): Topping[] {
    return Object.keys(entities).map(id => entities[parseInt(id, 10)]);
  }
 ...
}

及其为product.component

export class ProductsComponent implements OnInit {

  @Select(ToppingsState.toppings) toppings$: Observable<Topping[]>;

  constructor(private store: Store, private actions$: Actions) {}

  ngOnInit() {
    const state = this.store.dispatch(new LoadToppings());
    setTimeout(() => this.store.dispatch(new VisualizeToppings([1])), 2000);
    this.toppings$.subscribe((toppings) => {console.log('UUUU NEW TOPPINGS!!!')});
  }
}

当我调度VisualizeToppings操作时,我获得新的toppings值。在我的控制台中

action [Products] Load Toppings @ 10:57:59.735
getEntities {}
UUUU NEW TOPPINGS!!!
getEntities {1: {…}, 2: {…}}
UUUU NEW TOPPINGS!!!
action [Products] Visualize Toppings @ 10:58:01.744
getEntities {1: {…}, 2: {…}}
UUUU NEW TOPPINGS!!!

我改变了状态的另一部分。为什么在我调度VisualizeToppings操作时选择器会再次执行?我该怎么办?

1 个答案:

答案 0 :(得分:3)

@Selector存在一个已知问题,其中始终将容器状态类的模型假定为第一个参数。参见:https://github.com/ngxs/store/issues/386#issuecomment-395780734

这是您的问题...由于有第一个参数,您的选择器依赖于状态模型ToppingsStateModel和指定的ToppingsState.entities选择器。

  @Selector([ToppingsState.entities])
  static toppings(state: ToppingsStateModel, entities: {[id: number]: Topping}): Topping[] {
    return Object.keys(entities).map(id => entities[parseInt(id, 10)]);
  }

这将导致在ToppingsStateModel的任何部分更改时重新计算选择器。解决方法是,可以将选择器移动到不是State类的另一个类,并删除第一个参数。我将这些称为查询类。这称为元选择器,请参见此处的文档:https://ngxs.gitbook.io/ngxs/concepts/select#meta-selectors

此问题将作为NGXS v4中重大更改的一部分得到解决(请参见https://github.com/ngxs/store/issues/827),并且当前有一个PR标记,用于在NGXS v4到来之前更改此行为。参见:https://github.com/ngxs/store/pull/858

我希望这会有所帮助并解释问题。