Angular 2 - with ngFor, is it possible to update v

2020-02-10 13:24发布

问题:

I have a component 'bar' inside ngFor. I want to update its width with animation starting from the previous value to new one.

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 + '%' });
  }

}

But on each updateData() it looks like ngFor recreates the dom and BarComponent is constructed again. So even if 'station.perc' is the same, ngOnChanges() is fired.

And the transition keeps on restarting from 0 instead of starting from the previous value...

I probably miss a crucial point here but whats the clean workaround?

回答1:

I guess you should use trackBy option to customize the default tracking algorithm the ngFor directive:

view

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

component

trackByFn(index, item) {
  return index;
}

or a bit better use unique id:

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

See more details about the trackBy here:

  • https://angular.io/guide/template-syntax#ngfor-with-trackby

Hope Plunker Example will also help you.



标签: angular