Angular 2 Redux 在 NgFor 中不断重新渲染
Angular 2 Redux constantly re-rendering in NgFor
我在我的项目中使用 NGRX,并且在不断地重新渲染组件时遇到问题。
Store 每次都会生成全新的对象,如果存储数据相同,我不想重新渲染我的组件。我将表示组件的更改检测更改为 ChangeDetectionStrategy.OnPush
lodash 记忆 (_.memoization
),但它不起作用
店铺状态
export interface CardsState {
cardsA: CardA[];
cardsB: CardB[];
cardsC: CardC[];
}
然后将 Store state 映射到结构,如下所示
const entities = [{
cards: {
cardsB: [
{}
]
}
}];
并尝试防止每次通过 lodash 的记忆
更改商店时重新呈现 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 天时间了,快要死了,求求你帮忙!
我的母语不是英语,如有错误请见谅。
谢谢!
在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
如果你有:
<div *ngFor="let outer of outers">
<div *ngFor="let inner of outer.inners">
{{ inner }}
</div>
</div>
然后如果 outer
在某个时候发生变化,内部 ngFor 将重新呈现,这就是为什么您会看到来自 ngOnInit 的警报。但是,如果您将 trackBy 添加到外部 ngFor,并且它将其识别为相同的元素,那么您可以避免内部列表重新渲染,这是您当前的问题。
内部 trackBy 仅保留内部元素并防止重新创建这些元素。外层 trackBy 保留了外层元素,这使得内部元素也有机会被保留。
我在我的项目中使用 NGRX,并且在不断地重新渲染组件时遇到问题。
Store 每次都会生成全新的对象,如果存储数据相同,我不想重新渲染我的组件。我将表示组件的更改检测更改为 ChangeDetectionStrategy.OnPush
lodash 记忆 (_.memoization
),但它不起作用
店铺状态
export interface CardsState {
cardsA: CardA[];
cardsB: CardB[];
cardsC: CardC[];
}
然后将 Store state 映射到结构,如下所示
const entities = [{
cards: {
cardsB: [
{}
]
}
}];
并尝试防止每次通过 lodash 的记忆
更改商店时重新呈现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 天时间了,快要死了,求求你帮忙!
我的母语不是英语,如有错误请见谅。
谢谢!
在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
如果你有:
<div *ngFor="let outer of outers">
<div *ngFor="let inner of outer.inners">
{{ inner }}
</div>
</div>
然后如果 outer
在某个时候发生变化,内部 ngFor 将重新呈现,这就是为什么您会看到来自 ngOnInit 的警报。但是,如果您将 trackBy 添加到外部 ngFor,并且它将其识别为相同的元素,那么您可以避免内部列表重新渲染,这是您当前的问题。
内部 trackBy 仅保留内部元素并防止重新创建这些元素。外层 trackBy 保留了外层元素,这使得内部元素也有机会被保留。