* ngFor-通过ngrx更新数组时更新dom

时间:2019-02-18 08:56:10

标签: angular typescript rxjs

我正在使用* ngFor来显示数组中的值:

[
  {
    id: 1,
    name: 'item1'
  },   
  {
    id: 2,
    name: 'item2'
  }
]

html:

<div *ngFor="let item of (items$ | async); trackBy: trackById;">
   // more html to display data
</div

ts:

items$: Observable<any>;
trackById = trackByProperty('id');

ngOnInit() {
  this.items$ = this.store.pipe(select(selectors.itemsSelector));
}

trackByProperty<T = any>(property: keyof T) {
  return (index: number, object: T) => object[property];
}

这可以按预期工作,ngFor会在items$ array

中获取正确的当前值

我的问题是,当我使用items$更新ngrx数组时,它似乎没有捕获到新数组,也没有更新DOM

使用ngrx

来显示数据流
  1. 向reducer调度操作,发送一个新对象以添加到数组。

      this.store.dispatch(new actions.UpdateArray(
          { id: 3, name: 'item3' }
        )
      );
    
  2. Reducer采取此操作并使用更新后的数组更新商店状态(接收新项目并将其推入数组)。

    case actions.UPDATE_ARRAY: {
      const newItem = action.payload;
      const items = state.items;
      items.push(newItem);
      return {
        ...state,
        items
      };
    }
    
  3. 选择器更新。

我可以确认在reducer中注销action.payload时状态已正确更新。

有人知道为什么我没有在*ngFor中得到更新的数组吗?

忘记了,但是我正在使用changeDetection: ChangeDetectionStrategy.OnPush作为组件中的更改检测

谢谢!

更新:

我发现单击该组件时DOM实际上会更新。我希望无需进行更新

1 个答案:

答案 0 :(得分:1)

之所以会发生这种情况,是因为NgRx选择器使用了“备忘”功能,这有时会导致不良行为。

更改

case actions.UPDATE_ARRAY: {
  const newItem = action.payload;
  const items = state.items;
  items.push(newItem);
  return {
    ...state,
    items
  };
}

case actions.UPDATE_ARRAY: {
  const newItem = action.payload;
  const items = [...state.items, newItem]; // <-- creates new instance
  return {
    ...state,
    items
  };
}

应该解决问题。