Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid triggering change detection in a component using the method in the view?

I have a array with filters:

["BOX_NAMES", "BATHROOMS", "CONFERENCE_HALLS"]

and i show part of view when filter is active in *ngIf* directive like that:

*ngIf="isFilterActive(Filters.CONFERENCE_HALLS)"

isFilterActive function implementation:

if (this.officeService.selectedFilter[0] === Filters.SHOW_ALL) {
    return true;
  }
  return this.officeService.selectedFilter.includes(filter);
}

When i change filter, my view rerender lots of times. How to avoid this?

Of course my components are loaded in lazy loading.

like image 357
Michał Borzęcki Avatar asked Oct 28 '25 16:10

Michał Borzęcki


2 Answers

Firstly: Why is it a problem that your component renders a lot of times? You should not have any performance issues, since *ngIf is designed for those operations.

The reason why your component renders so often because Angular triggers ChangeDetection whenever something changes in your component. Then, all variables, directives in your view are checked if something changed.

What you could do in order to avoid that is to prevent doing that in your component decorator by adding another changeDetectionStrategy like this:

@Component({
    // ...other ocmponent decorator properties
    changeDetection: ChangeDetectionStrategy.OnPush
})

Now your component only triggers changeDetection if your @Input() parameters change, or if you specifically tell it to. So now, whenever you change your filters (or do something else in your component which is not triggered through @Input() parameters, you need to trigger changeDetection manually.

Therefore, first inject it via DependencyInjection in your constructor:

constructor(private cd: ChangeDetectorRef) {}

Then, call it after you executed the change:

this.cd.detectChanges();

Hope that helps.

like image 63
dave0688 Avatar answered Oct 30 '25 07:10

dave0688


This is caused by the fact that you use a function to evaluate the return value.

If you set the result of this function in a property in your .ts file, and then use this property in your *ngIf, then you won't have the issue. This is caused because Angular doesn't know what value is to be checked, so it calls the function everytime there is a changeDetection triggered.

Here is an example given your sample :

activeFilter;

onFilterChange(event) {
  if (this.officeService.selectedFilter[0] === Filters.SHOW_ALL) {
    this.activeFilter = true;
  }
  this.activeFilter = this.officeService.selectedFilter.includes(filter);
}

*ngIf="activeFilter"

Of course, this is a sample code that needs more thoughts and serves as a mere incomplete example.


You can also improve the way the changeDetection is triggered by using the ChangeDetectionStrategy : OnPush in the decorator of the component so that change detection cycles will only occur when an @Input() in your component has been changed.

like image 30
Alex Beugnet Avatar answered Oct 30 '25 08:10

Alex Beugnet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!