Force change detection on pipe?


#1

I have an issue with a custom tab bar component and a pipe which is driving me crazy.

If you have a look at this repo, you will see that I took the :nng: 2.5.0 template, modified the app/item/items.component.ts for filtering a listview for All|Odd|Even items. I have a custom TabsBar on top and a couple of buttons in the bottom which both do the same thing (update the filter that is fed to the pipe in the listview).

When I run the code on a device/simulator and use the top bar with the custom component, it will change the filter that the listview uses, but it will not update the view. When I use the buttons in the bottom, which update the same filter, it updates the listview immediately.

I already tried to set the pipe to an un-pure pipe, recreating the array of objects this.segmentFilter=[...this.segmentFilter] and calling the refresh method of the listview, which all don’t work.

To make things even stranger, when I add a setInterval in the ngOnInit which literally does nothing, it will update the listview when that interval occurs. Somehow it seems that a default Button triggers some kind of change detection on the pipe or something and the setInterval as well, that I also need to trigger on the tap event of my custom TabsBar component?

Any thoughts on what I am missing here?


#2

I found a very simple solution which works great, I just need to tell angular to force change detection. I guess the ui elements that come with NS do that automatically.

import { Component, OnInit, ChangeDetectorRef } from "@angular/core";

private onTabSelect(tab) {
    this.segmentFilter=tab.value.code;
    this.cdr.detectChanges(); // tell angular to do change detection
  }

(edited)


#3

Hey, mate! I’ve found myself in this problem a while ago and this article really helped me out.

To sum up: when using an OnPush change detection strategy, you should explicitly tell angular where it should detect a change. If you use the Default strategy, the change will be detected anytime it occurs. Between these strategy, the Default one can lead to some performance issues I reckon, since you do not control when to detect a change (it will be done all the time)

I didn’t know about this detectChanges(). I used markForCheck() instead. Don’t know neither if there are many differences (there might be) between them nor if there are differences in performance.

Cheers =D