Когда выполняются селекторы?ngxs - PullRequest
0 голосов
/ 22 февраля 2019

live demo 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, я получаю новое значение добавок.В моей консоли у меня есть

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 голосов
/ 22 февраля 2019

Существует известная проблема с @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

Надеюсь, это поможет и объяснит проблему.

...