Reputation: 1553
Context:
Problem: Every single item in my list is destroyed and recreated even though the input is the same
The reason why the list is replaced by another list is because an observable is behind it (angularfire2). How can I avoid the entire list reloading? Is there a way of maybe creating separate observable for each item in that list and instead let those listen for changes?
Uncertain whether this should be tagged with angularfire2 since I can create the same problem in angular2. Leaving some angularfire2 in comments
Plnkr: http://plnkr.co/edit/qSX9nRGGVNUkD5qIHOMl?p=preview
import { Component, Input } from '@angular/core';
//import { AngularFire, FirebaseListObservable } from 'angularfire2';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Component({
selector: 'my-app',
template: '<p *ngFor="let item of items | async"><test [options]="item"></test></p>'
})
export class AppComponent {
public items = new BehaviorSubject([{bah: 1},{bah: 2},{bah: 3}]);
//public items: FirebaseListObservable<any[]>;
constructor() {//af: AngularFire) {
setTimeout(() => {
this.items.next([{bah: 1},{bah: 2},{bah: 3},{bah: 4}]);
},3000);
/*this.items = af.database.list('/items');
this.items.push(1);
setTimeout(() => {
this.items.push(2);
},3000);*/
}
}
@Component({
selector: 'test',
template: '{{JSON.stringify(options)}}'
})
export class TestComponent {
public JSON = JSON;
@Input() options;
ngOnChanges(changes) { console.log('ngOnChanges'); }
ngOnDestroy() { console.log('ngOnDestroy'); }
ngOnInit() { console.log('ngOnInit'); }
}
Upvotes: 1
Views: 715
Reputation: 14395
You can use trackBy
:
template: '<p *ngFor="let item of items | async; trackBy: itemToIndex" class="my-animation"><test [options]="item"></test></p>'
Track by should be a function, so your plnkr example should be updated to:
itemToIndex(item: any){
return item.index;
}
Upvotes: 2