简体   繁体   English

使用不变性时,悬停闪烁

[英]Hover flickering when using immutability

I have a list of simple objects that I want to display, so I create components using *ngFor . 我有一个要显示的简单对象列表,因此我使用*ngFor创建组件。 Every component has css hover effect that changes its background. 每个组件都有css悬停效果,可更改其背景。 When I change object's property in an immutable way (create new array with replaced one object) the background of the associated component often flickers. 当我以不变的方式更改对象的属性(用替换的一个对象创建新数组)时,关联组件的背景经常闪烁。

List component: 列表组件:

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);
  }
}

List item component: 列表项组件:

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

Here is a demo: https://stackblitz.com/edit/angular-pmdjqu?embed=1&file=app/listItem.component.ts 这是一个演示: https : //stackblitz.com/edit/angular-pmdjqu?embed=1&file= app/ listItem.component.ts

How can I fix this problem? 我该如何解决这个问题? Is Angular broken or am I doing something wrong? Angular坏了还是我做错了什么? Maybe Angular is not designed for immutable manipulations? 也许Angular不是为不可变的操作设计的?

(In React such problem does not exist: https://stackblitz.com/edit/react-bdul7z?file=index.js ) (在React中不存在这样的问题: https ://stackblitz.com/edit/react-bdul7z?file =index.js

You provided key for react list. 您提供了反应列表的密钥

<ListItem key={item.name}
          ^^^^^^^^^^^^^^^

But forgot to apply ngTrackBy option in angular 但是忘了在angular中应用ngTrackBy选项

<list-item *ngFor="let item of items; trackBy: trackByFn"
                                      ^^^^^^^^^^^^^^^^^^

trackByFn(i, x) {
  return x.name;
}

Angular Example 角度示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM