1

Here is my plunker: https://plnkr.co/edit/QPqciUngXeby2uECbokx?p=preview (You might have to click on stop and run a few times for it to load properly)

The table is not changing.

But when you take

changeDetection: ChangeDetectionStrategy.OnPush

out, the table changes.

My understanding is that with OnPush, when the @Input changes, change detection will fire. In this case, the @Input is [value], which links to this.testData.

Why is it not changing?

techguy2000
  • 4,861
  • 6
  • 32
  • 48

1 Answers1

1

Because with onPush change detection runs when an input is changed or when an event that was listened to was handled.

If you change this.testData, then change detection needs to run to update the [value]="testData" binding. If that happens, change detection will run for <p-dataTable> because its input changed.

There is no input on App that has changed, therefore no change detection.

You can mark App for check using ChangeDetectorRef.markForCheck()

Plunker example

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • So it looks like Angular stop listening for @Input change at the child level when the Root is using OnPush, is that correct? When I use `[value]="testData$ | async"`, the table updates, does the async pipe adds the markForCheck automatically? – techguy2000 Feb 17 '17 at 15:42
  • Your explanations is a bit backwards. Change detection needs to be run for the `App` component, then when it recognizes the change, it updates the bindings in the template. `setTimeout()` doesn't cause change detection to run when the component uses `OnPush`. This is when the `@Input()` of `` is updated. If `` uses `OnPush` this would cause change detection to be run for ``. Yes `async` causes change detection to be run in `` every time `testData$` emits an event. Hope this helps. – Günter Zöchbauer Feb 17 '17 at 15:46
  • My original understand before your answer is that when App uses OnPush, any components under App will inherit the OnPush strategy. Is that correct? And [value] is the @Input() in , right? So in my original post, the @Input() in changed, but the table is not refreshed. So it seems like Angular ignores the @Input() change at the child level when it detects no change on the parent level. I am using a simple component instead of p-dataTable here: https://plnkr.co/edit/xMu3km7XqvdT2pqCjRmi?p=preview – techguy2000 Feb 17 '17 at 16:05
  • No, `OnPush` won't be inherited by children. Angular Change detection runs from the root component to the leaf components. If there is a component that is set to `OnPush`, then change detection will skip this detection for this component which includes it's children. This doesn't mean they are using `OnPush` as well, but they are affected by parents that use `OnPush` though. "And `[value]` is the `@Input()` in ``, right?". That's right. "So in my original post, the `@Input()` in `` changed, but the table is not refreshed." – Günter Zöchbauer Feb 17 '17 at 16:12
  • No, the input is **not** changed, because change detection for **`App` was not** run and therefore it wasn't recognized by Angular that the modified `this.testData` would need to be passed to the `@Input()` of ``. This is why nothing was happening. – Günter Zöchbauer Feb 17 '17 at 16:12
  • [value]="testData" tells me that @Input() value is inside p-dataTable code. Is that right? When this.testData changes, [value] doesn't change because Angular's change detection isn't fired at the App level. Is that right? But any event firing on child component will trigger the change detection on the App level. That's why the async pipe works. This is my plunker with the event triggering App level change detection: https://plnkr.co/edit/yMeFOMV4jAuDDlnnrawM?p=preview – techguy2000 Feb 17 '17 at 16:33
  • "`[value]="testData"` tells me that `@Input() value` is inside `p-dataTable code. Is that right?" - exactly. "Angular's change detection isn't fired at the App level. Is that right?` - exactly. "But any event firing on child component will trigger the change detection on the App level." - yes, for DOM events because they bubble. "That's why the async pipe works.". No, the async pipe causes change detection in the `App` component. Sorry, that was a mistake in my first comment above where I stated that it causes the child component to be checked. – Günter Zöchbauer Feb 17 '17 at 17:32
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136013/discussion-between-techguy2000-and-gunter-zochbauer). – techguy2000 Feb 18 '17 at 06:53