NgFor中的Angular 2 Redux不断重新渲染
我在我的项目中使用NGRX,并且在不断地重新渲染组件方面存在问题。 每次存储都会生成全新的对象,如果存储数据相同,我不想重新渲染我的组件。我将演示文稿组件的更改检测更改为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
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 likereturn item.entityId+item.entityType;}
在trackbyfn中使用key like谢谢你的回答!当我只有一个ngFor像这样的ngFor时,这很好用代码>但它不适用于内部ngForuser内部循环的另一个trackBy。我在我的记忆功能中使用了key-likereturn-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一起工作。你能把这个作为答案,然后我可以把你的答案标记为解决方案吗?