Angular 2 — с помощью ngFor возможно ли обновлять значения без перестройки dom?

#angular

#angular

Вопрос:

У меня есть компонент ‘bar’ внутри ngFor. Я хочу обновить его ширину с помощью анимации, начиная с предыдущего значения до нового.

HTML :

 <div *ngFor="let station of stations" class="station">
    <bar [perc]="station.perc" class="bar"></bar>
</div>
  

ParentComponent :

 ngOnInit(){
    setInterval(() => this.updateData(), 10000);
  }

  updateData(){
    const url = 'http://....';
    this.http.get(url)
      .map(res => res.json())
      .subscribe(data => {

        this.stations = data;

      });
  }
  

BarComponent

 export class BarComponent {

  @Input() perc;

  constructor(private element: ElementRef){}

  ngOnChanges(changes: any): void {
    let perc = changes.perc.currentValue;
    TweenMax.to(this.element.nativeElement, 1, { width: perc   '%' });
  }

}
  

Но при каждом updateData() похоже, что ngFor воссоздает dom, и BarComponent создается снова. Таким образом, даже если ‘station.perc’ совпадает, запускается ngOnChanges() .

И переход продолжает перезапускаться с 0 вместо того, чтобы начинаться с предыдущего значения…

Я, вероятно, упускаю важный момент здесь, но каков чистый обходной путь?

Ответ №1:

Я думаю, вам следует использовать trackBy option для настройки алгоритма отслеживания по умолчанию ngFor в директиве:

Вид

 <div *ngFor="let station of stations; let i = index; trackBy: trackByFn" class="station">
  <bar [perc]="station.perc" class="bar"></bar>
</div>
  

компонент

 trackByFn(index, item) {
  return index;
}
  

или немного лучше использовать уникальный идентификатор:

 trackByFn(index, station) {
  return station.id;
}
  

Более подробную информацию о trackBy смотрите здесь:

Надеюсь, пример Plunker также поможет вам.

Комментарии:

1. Круто, ты спас меня, братан

2. Просто обновите ссылку на — angular.io/guide/template-syntax#ngfor-with-trackby