I'm trying to create a application with angular 2; I want when last element rendered in *ngFor,execute a function, something like this, tag is <img>
:
<img *ngFor="let image of template.previewImages; let i = index" [src]="image" [class.hs_visible]="i==0" />
Function name is
animation(){console.log('enter');}
See this Plunker for the solution I managed to come up with.
It might not be elegant, but it (mostly) works!
Basically, *ngFor
helpfully provides a handful of values, like index, even, odd, and fortunately enough, first and last booleans that evaluate to true for the respective iterations. First, you have to expose the values as local variables in the *ngFor
exactly as you would the index. Then, you have to get Angular to call the function from the template, which you can do as if you were binding a value to the template but with a tertiary conditional (that returns null for false evaluations).
<div *ngFor="let i of stuff; let l = last ">
{{ i }} {{ l === true ? callOnLastIteration() : null}}
</div>
I say "(mostly) works" because it seems that if you try to bind to a property inside of the *ngFor
-ed element, other than the one you are iterating on and then change value of said property inside of the function called at the last iteration, you'll get undesired behavior and errors from Angular's change propagation system. See the Plunker for details.
It would be better if you can create a directive which will do the same. You just need to pass the last
flag to directive and it will call desired function when last element gets rendered.
View
<p class="my-element"
*ngFor="let i of stuff; let l = last"
[lastElement]="l" (lastFunc)="test()">
{{i}}
</p>
Directive
import { Directive, ElementRef, Input, Output, EventEmitter } from '@angular/core';
@Directive({
selector: '[lastElement]'
})
export class LastElementDirective {
@Input() lastElement : any;
@Output() lastFunc = new EventEmitter();
constructor(private el: ElementRef) {
this.setTimer(); //somehow lastElem value is available on next tick
}
setTimer(){
setTimeout(() => {
if(this.lastElem) this.lastFunc.emit();
}, 0);
}
}
Plunkr in action
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With