NgFor中的Angular 2 Redux不断重新渲染

NgFor中的Angular 2 Redux不断重新渲染,angular,memoization,ngrx,ngrx-store,Angular,Memoization,Ngrx,Ngrx Store,我在我的项目中使用NGRX,并且在不断地重新渲染组件方面存在问题。 每次存储都会生成全新的对象,如果存储数据相同,我不想重新渲染我的组件。我将演示文稿组件的更改检测更改为ChangeDetectionStrategy.OnPushlodash memorization(.memorization),但它不起作用 储存状态 export interface CardsState { cardsA: CardA[]; cardsB: CardB[]; cardsC: Card

我在我的项目中使用NGRX,并且在不断地重新渲染组件方面存在问题。 每次存储都会生成全新的对象,如果存储数据相同,我不想重新渲染我的组件。我将演示文稿组件的更改检测更改为
ChangeDetectionStrategy.OnPush
lodash memorization(
.memorization
),但它不起作用

储存状态

export interface CardsState {
    cardsA: CardA[];
    cardsB: CardB[];
    cardsC: CardC[];
}
然后将存储状态映射到如下结构

const entities = [{
 cards: {
  cardsB: [
   {}
  ]
 }
}];
并试图防止每次从lodash通过memoize更改存储时重新呈现
cardsB

export const memoizeCardBFunc = _.memoize((cardB: CardB): CardB => {
  return _.cloneDeep(cardB);
}, (cardB: CardB) => cardB.entityType + cardB.entityId);
在我的智能组件中,我有下一个html

<div *ngFor="let entity of entities | async">
    <div *ngFor="let cardB of entity.cards.cardsB">
        <card-b [cardStateModel]="cardB"></card-b>
    </div>
</div>

令我惊讶的是,它正确地与一个ngFor一起工作,但如果我有两个ngFor,它就不工作了

<div *ngFor="let cardB of entity.cards.cardsB">
    <card-b [cardStateModel]="cardB"></card-b>
</div>

我已经为此花了两天的时间,它快把我累死了,求求你,救命

我不是以英语为母语的人,抱歉出错


谢谢

在For循环中使用trackBy。它将跟踪状态,并在数据发生更改时触发重新渲染

    <div *ngFor="let cardB of entity.cards.cardsB;let i = index; trackBy: trackByFn">
        <card-b [cardStateModel]="cardB"></card-b>
    </div>

trackByFn(index, item) {
    return index; // or item.id
  }

trackByFn(索引,项目){
返回索引;//或item.id
}
阅读下面的文档,您将了解更多。
在For循环中使用trackBy。它将跟踪状态,并在数据发生更改时触发重新渲染

    <div *ngFor="let cardB of entity.cards.cardsB;let i = index; trackBy: trackByFn">
        <card-b [cardStateModel]="cardB"></card-b>
    </div>

trackByFn(index, item) {
    return index; // or item.id
  }

trackByFn(索引,项目){
返回索引;//或item.id
}
阅读下面的文档,您将了解更多。 如果您有:

<div *ngFor="let outer of outers">
    <div *ngFor="let inner of outer.inners">
       {{ inner }}
    </div>
</div>

{{inner}}
然后,如果
outer
在某个点发生更改,则内部ngFor将重新呈现,这就是您看到来自ngOnInit的警报的原因。但是,如果您将trackBy添加到外部ngFor,并且它将其识别为同一元素,那么您可以避免内部列表的重新渲染,这是您当前的问题

内部trackBy仅保留内部元素并防止重新创建这些元素。外部trackBy保留了外部元素,这使得内部元素也有机会被保留。

如果您有:

<div *ngFor="let outer of outers">
    <div *ngFor="let inner of outer.inners">
       {{ inner }}
    </div>
</div>

{{inner}}
然后,如果
outer
在某个点发生更改,则内部ngFor将重新呈现,这就是您看到来自ngOnInit的警报的原因。但是,如果您将trackBy添加到外部ngFor,并且它将其识别为同一元素,那么您可以避免内部列表的重新渲染,这是您当前的问题


内部trackBy仅保留内部元素并防止重新创建这些元素。外部trackBy保留了外部元素,这使得内部元素也有机会被保留。

谢谢您的回答!当我只有一个像这样的ngFor时,这很有效
*ngFor=“let cardB of entities[0].cards.cardsB;
但它不适用于内部ngForuser内部循环的另一个trackBy。我在我的记忆功能中使用key like
return item.entityId+item.entityType;}
在trackbyfn中使用key like谢谢你的回答!当我只有一个ngFor像这样的ngFor时,这很好用但它不适用于内部ngForuser内部循环的另一个trackBy。我在我的记忆功能中使用了key-like
return-item.entityId+item.entityType;}
在trackbyfn中,我不确定您为什么或如何使用u.memoize和u.cloneDeep,但这听起来像是您在减速器中做错了什么。如果您的存储数据保持不变,那么它首先就不应该返回新对象。@matmo@Jonnysai我的问题很严重。In不适用于内部ngFor。您可以删除第一个ngFor和第二个对
*ngFor=“let cardB of entities[0].cards.cardsB;trackBy:trackByB”的更改,然后它就可以工作了。我需要你的帮助(看起来你需要在外面安装一个追踪装置ngFor@matmo我不知道为什么,但它可以与outer trackBy一起使用。你能把这个作为答案,然后我就可以把你的答案标记为解决方案吗?我不知道你为什么或者如何使用u0.memoize和0.cloneDeep,但这听起来像是你在简化程序中做错了什么。如果你的存储数据保持不变,它就不会改变首先不能返回新对象。@matmo@Jonnysai这是我的一个问题。in不适用于内部ngFor。您可以删除第一个ngFor,然后将第二个更改更改为
*ngFor=“let cardB of entities[0]。cards.cardsB;trackBy:trackByB”
,它可以工作。我需要内部ngFor(看起来你需要在外面安装一个追踪装置ngFor@matmo我不知道为什么,但它和outer trackBy一起工作。你能把这个作为答案,然后我可以把你的答案标记为解决方案吗?