如何独立触发 NGRX Selector foreach children 组件

How to fire NGRX Selector foreach children component independently

我有一个组件,它在仪表板中充当小部件。因此,我将使用 *ngFor 来呈现与仪表板一样多的小部件。 WidgetComponent 只是一个,并且通过 @Input() 从 parent.

接收它的一部分数据

parent

<app-widget *ngFor="let widget of widgets"
      [widget]="widget">
</app-widget>

在 child 中,我使用 NGRX 选择器监听一个事件:

this.store.pipe(
   select(fromStore.selectPage, {widgetId: this.widgetId, page: this.paginator.currentPage}),
   distinctUntilChanged() // can be used, but is unnecessary
).subscribe(rows => {
   console.log(rows);
});

当我想更改页面时,我在我的商店中发送了一个新事件:

ngAfterViewInit(): void {
  const pages = currentPage < 3
    ? [1, 2, 3]
    : [currentPage - 1, currentPage, currentPage + 1];

  const request: PaginatedData = {
    widgetId: this.widget.id,
    itemsPerPage: paginator.itemsPerPage,
    pages
  };

  this.store.dispatch(updatePagesAction({request}));
}

选择器:

export const selectPage = createSelector(selectState, (state, props) => {
  const table = state.widgetTables.find(x => x.widgetId === props.widgetId);
  if (typeof table === 'undefined') {
    return [];
  }

  const existingPageKey = Object.keys(table.pages).find(key => key === props.page.toString());
  return existingPageKey ? table.pages[existingPageKey] : [];
});

问题: 当我为一个小部件发送一个动作时,将触发所有同时在商店中收听的小部件的选择器。

我只需要为 in cause 小部件触发选择器。问题可能是我对所有小部件使用相同的选择器?

我不能在我的小部件组件 pipe() 中使用 filter() 因为即使我使用类似 filter(x => x.widgetId === this.widget.Id) 的东西,事件也会被触发并且所有小部件都会再次接收数据, 即使等于最后一个值。

啊,我知道:这可能是由于每次更改时,我的商店 return 一个新状态(对于所有小部件),因此所有选择器都被触发。

此外,我将此功能存储在一个运行良好的服务中,但是因为该应用程序已经在另一个模块中使用了 ngrx,所以我认为最好对齐所有必须的数据保存在内存中供以后使用,保存在 ngrx 存储中(不使用自定义服务)。

谢谢

我将如何解决这个问题

我认为你可以使用 returns 选择器的函数来代替,尝试像下面那样实现

export const selectPageWith = ({widgetId, page}: widgetId: number, page: any) => 
  createSelector(selectState, state => {
    const table = state.widgetTables.find(x => x.widgetId === widgetId);
    if (typeof table === 'undefined') {
      return [];
    }
    const existingPageKey = Object.keys(table.pages).find(key => key === page.toString());
     return existingPageKey ? table.pages[existingPageKey] : [];
  })

现在您可以像这样在您的组件中使用它

this.store.pipe(
   select(fromStore.selectPageWith({widgetId: this.widgetId, page: this.paginator.currentPage}),
   distinctUntilChanged() // can be used, but is unnecessary
).subscribe(rows => {
   console.log(rows);
});

说明

简单地说,我们正在尝试为每个小部件创建唯一的选择器。通过创建一个returns选择器的函数,不同的参数为每个小部件产生不同的选择器