我有一个我想要显示的简单对象列表,因此我使用*ngFor
创建组件。每个组件都有css悬停效果,可以改变其背景。当我以不可变的方式更改对象的属性(使用替换的一个对象创建新数组)时,关联组件的背景经常会闪烁。
列表组件:
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'my-app',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<list-item *ngFor="let item of items"
[item]="item"
(toggle)="onToggle(item)"
></list-item>
`,
})
export class AppComponent {
items = [
{ name: 'item1', toggled: false },
{ name: 'item2 ', toggled: true },
{ name: 'item3', toggled: false }
];
onToggle(item) {
const updatedItem = {
...item,
toggled: !item.toggled
};
this.items = this.items.map(item => item.name === updatedItem.name ? updatedItem : item);
}
}
列出项目组件:
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'list-item',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="container">
<span>{{ item.name }}: {{ item.toggled }}</span>
<button (click)="toggle.emit()">Toggle!</button>
</div>
`,
styles: [`
.container {
width: 400px;
height: 50px;
border: 1px solid black;
display: flex;
padding: 20px;
justify-content: space-between;
align-items: center;
}
.container:hover {
background-color: yellow;
}
`]
})
export class ListItemComponent {
@Input() item: Item;
@Output() toggle: EventEmitter<void> = new EventEmitter<void>();
}
export interface Item {
name: string;
toggled: boolean;
}
以下是演示:https://stackblitz.com/edit/angular-pmdjqu?embed=1&file=app/listItem.component.ts
如何解决此问题? Angular被破坏了还是我做错了什么? 也许Angular不是为不可变的操作而设计的?
(在React中这样的问题不存在:https://stackblitz.com/edit/react-bdul7z?file=index.js)
答案 0 :(得分:2)
您为反应列表提供了key。
<ListItem key={item.name}
^^^^^^^^^^^^^^^
但忘了在角色
中应用ngTrackBy选项<list-item *ngFor="let item of items; trackBy: trackByFn"
^^^^^^^^^^^^^^^^^^
trackByFn(i, x) {
return x.name;
}
<强> Angular Example 强>