2017-06-15 109 views
0

我在我的项目中使用NGRX,并且在不断地重新渲染组件时遇到问题。 商店每次产生全新的对象,如果商店数据相同,我不想重新渲染我的组件。我改改呈现组件检测到ChangeDetectionStrategy.OnPush lodash记忆化(_.memoization),但它不工作的商店Angular 2 Redux不断在NgFor中重新渲染

export interface CardsState { 
    cardsA: CardA[]; 
    cardsB: CardB[]; 
    cardsC: CardC[]; 
} 

然后映射存储状态,结构,这个

const entities = [{ 
cards: { 
    cardsB: [ 
    {} 
    ] 
} 
}]; 

,并试图的

国家防止每当店铺通过记录变更时重新呈现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> 

我已经连续2天过了,它会让我失望,请帮助!

我不是英语母语的人,对错误感到抱歉。

谢谢!

+0

我不确定你为什么或者如何使用_.memoize和_.cloneDeep,但是这听起来像是你的减速器出了问题。如果您的商店数据保持不变,则不应首先返回新对象。 – matmo

+0

@matmo @Jonnysai这是一个与我的问题https://plnkr.co/edit/gbjdubPeZQXo7j6L3E6w?p=preview的蹲点。不适用于内部ngFor。你可以删除第一个ngFor和第二个改变到'* ngFor =“让cardB的实体[0] .cards.cardsB; trackBy:trackByB”'并且它工作。我需要内部ngFor( –

+0

似乎你需要一个trackBy在外部ngFor – matmo

回答

1

如果您有:

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

那么,如果在某一点outer变化,内ngFor将重新呈现,这就是为什么你看到ngOnInit警报。但是,如果将trackBy添加到外部ngFor,并将其识别为相同的元素,则可以避免内部列表重新呈现,这是您当前的问题。

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

1

在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 
    } 

阅读下面的文档,你会明白更多。 https://v2.angular.io/docs/ts/latest/api/common/index/NgFor-directive.html

+0

谢谢你的回答!这个工作很好,当我只有一个ngFor就像这样'* ngFor =“让cardB的entities [0] .cards。cardsB;'但它不适用于内部ngFor –

+0

用户另一个trackBy内部循环。 – CharanRoot

+0

我使用键在我的memoization函数'return item.entityId + item.entityType;}'in trackByFn –