Angular - Как не перестраивать список, созданный с помощью * ng. В любое время запускается событие в каждом элементе списка - PullRequest
0 голосов
/ 29 декабря 2018

У меня есть простой список <div>, сгенерированный с использованием директивы *ngFor, что-то вроде

<div *ngFor="let item of items() | async ; let i=index" 
  [ngClass]="getItemClass(i)"
  (click)="itemClick(i)"</div>

Как видите, список заполняется асинхронно каждый раз, когда Observable возвращается методом items()излучает.В моем случае такой Observable является ReplaySubject, если это может быть полезно знать.Затем я определяю классы, которые будут применены к каждому элементу <div>, используя метод getItemClass.

Я также хочу реагировать на событие щелчка по каждому элементу, используя метод itemClick(i: number).

Проблема

Каждый раз, когда нажимается элемент div, т. Е. Каждый раз, когда запускается метод itemClick(i: number), кажется, что весь список <div>с перестроен.Я прихожу к такому выводу, наблюдая, что при каждом нажатии на элемент div также запускается метод items().

Вопрос

Можно ли избежатьвосстановить список при нажатии одного из элементов <div>?Я уже установил changeDetection на OnPush , но это, похоже, не решает мою проблему.

1 Ответ

0 голосов
/ 29 декабря 2018

Да, даже с onPush обнаружение изменений будет запущено.И это приведет к оценке метода index ().Это как-то потеряно в документации.Любое событие, которое будет отображаться в коде zone.js, будет вызывать обнаружение изменений для каждого компонента от корня до этого компонента.Установка onPush не помешает этому.Чтобы избежать повторного создания компонентов в цикле, вам нужно добавить trackBy.

В ваш HTML-шаблон:

<li *ngFor="let hr of heroes;trackBy: trackByFn">{{hr.name}}</li>

, а затем в компоненте вы должны определить функцию:

trackByFn(index, item) {    
   return item.id  
}

Элемент передается из цикла.и если идентификатор этого элемента не изменится, элемент не будет воссоздан.

Также я бы избавился от метода index () и заменил его переменной.Как я уже упоминал, он будет оцениваться каждый раз, когда запускается обнаружение изменений.Я написал статью о некоторых приемах повышения производительности, которые вы можете сделать, чтобы ускорить работу вашего приложения.

https://medium.com/12-developer-labors/some-things-i-wish-i-knew-before-i-start-to-work-with-angular-part-2-performance-47cd834dc409

...