0
votes

I understand that the change detection will fire for OnPush marked component if the input property changes (there are others way too).

But I don't have an input property in my child component and I have a service injected into my component. I have subscribed the observable exposed by the service inside this child component. Now inside the subscribe callback method I change one of my child component's private property's value. The template of the component is bonded to this property.

So the problem is when the observer publishes an event my subscriber callback is called, and it changes the property value but the view doesn't reflect the changes. The UI only updates when I click somewhere in my page.

changeDetection: ChangeDetectionStrategy.OnPush

Update 1: Plunker added

1
Have you tried to use async pipe or cdRef.markForCheck()? And where is your code? - yurzui
I can't use asynchronous pipe as my template is binded to a private property of component example a string. And CDR.markForCheck() I read but isn't it an overkill as it will go back till the anscetor root component by firing CD? I don't know how to post a plunker, will Google and add shortly. Thanks. - thinkmmk
No, markForCheck doesn't go back to the ancestor root. That's ApplicationRef.tick(). markForCheck makes the component not being skipped on the next change detection turn. - Günter Zöchbauer
Actually I went through this, here the last paragraph of the answer says it fires till root stackoverflow.com/questions/35386822/… - thinkmmk
don't bind to private prop - it is not AOT compatible. - Julia Passynkova

1 Answers

2
votes

So, the comments are totally right. markForCheck() will cause it to go up to the root, but that's not a bad thing..

If your app goes: root > section > page > area > row > list and you make changes on your list then you would want to notify the parent items that changes have happened. Maybe you need to grow bigger now that more data is loaded, or trigger a scroll, or all sorts of stuff.

Remember though that you'll have to wait for a tick and if you're using onPush() on the parents as well without being notified that a child has changed with markForCheck() the detection will never reach your child, that's why it goes all the way.

The other method is manually triggering with detectChanges() This will run only on the local component and treats the node that called detectChanges() as the root..

Also, if you're displaying any property of your component it isn't technically Private. Javascript will allow it of course but test suites and I think even the compiler will complain. if you for whatever MUST do it, display it with a public getter.. like this:

Private _mySuperSecret: 'I am Batman';
Public get mySecret() { return this._mySuperSecret; };