I'm trying to understand what is happening here. I created a new Angular project, in app.component.html:
<img [src]="getDemoImg()">
app.component.ts:
getDemoImg(){
console.log('why so many logs???');
return 'https://historia.nationalgeographic.com.es/medio/2019/12/11/coliseo-roma_2924b6ae_1280x720.jpg'
}
console.log is printing 4 times that message, it seems the function is called 4 times, what is wrong here?
reproducible example: https://stackblitz.com/edit/angular-ivy-d5hdmo?file=src/app/app.component.html
CodePudding user response:
Nothing is wrong, all functions in your html will be called when change detection runs. Many things can cause change detection to run, and when it does run the framework will recheck all of the variables in your html to see if they changed.
There is no way to know that your function won't return something different each time, so if the framework detects a change, it needs to call the function again in order to make sure your html is up to date.
You need to be very careful when calling functions directly in html as opposed to attaching them to an event, especially if those functions take lots of time or make http requests. You might end up bogging down your application, or worse - requesting way too much data from a pay as you go database.
If you want to disable automatic change detection on a component you can use the OnPush
strategy:
@Component({
selector: 'my-component',
changeDetection: ChangeDetectionStrategy.OnPush,
template: ...
})
export class MyComponent {
Now your html will only re-render if you explicitly invoke change detection.
constructor(private changeDetectorRef: ChangeDetectorRef) {}
refresh() {
this.changeDetectorRef.detectChanges();
}
Example with the OnPush
strategy:
https://stackblitz.com/edit/angular-ivy-z39ayo?file=src/app/app.component.ts
More info on change detection:
https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/
https://mokkapps.de/blog/the-last-guide-for-angular-change-detection-you-will-ever-need/
CodePudding user response:
The best way is to use a variable to binding src or another attribute and update the variable if you need.