Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - with ngFor, is it possible to update values without rebuilding the dom?

Tags:

angular

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?

like image 983
sebap Avatar asked Oct 11 '16 14:10

sebap


People also ask

What is trackBy in ngFor?

Angular provides a method called trackBy , which is used to track our incoming data every time we get a request from an API. Suppose we have some data coming from an API request into the collection, and we need to change the data over the web page using the ngFor directive.

Can we use ngFor inside ngIf?

While you are not allowed to use *ngIf and *ngFor in the same div (it will gives an error in the runtime) you can nest the *ngIf in the *ngFor to get the desired behavior.

Is ngFor a directive?

NgFor is a structural directive, meaning that it changes the structure of the DOM . It's point is to repeat a given HTML template once for each value in an array, each time passing it the array value as context for string interpolation or binding.

What does ngFor do in angular?

*ngFor is a predefined directive in Angular. It accepts an array to iterate data over atemplate to replicate the template with different data. It's the same as the forEach() method in JavaScript, which also iterates over an array.


1 Answers

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.

like image 125
yurzui Avatar answered Sep 21 '22 06:09

yurzui