简体   繁体   中英

Angular 2 change detection, ngClass model gets updated by sibling component but the template does't get refreshed

I have a setup that goes something like this:

main.ts - Usual structure, no problem there

app.component.ts - Usual structure, no problem there

app.component.html

<navigation-cart></navigation-cart>
<div id="content">
    ... other stuff ...
    <start-arrow></start-arrow>
</div>

ui-layout.service.ts - This service takes care of opening and closing all regions in the app.

import {Injectable} from '@angular/core';

@Injectable()

export class UiLayoutService {

    startArrowIsVisible: boolean = true;

    openStartArrow() {
        this.startArrowIsVisible = true;
        console.log('openStartArrow', this.startArrowIsVisible);
    }

    closeStartArrow() {
        this.startArrowIsVisible = false;
        console.log('closeStartArrow', this.startArrowIsVisible);
    }
    ...

}

Both navigation-cart.component.ts and start-arrow.component.ts have the UiLayoutService injected

start-arrow.component.html

<a (click)="uiLayoutService.openStartArrow();">Open</a>
<a (click)="uiLayoutService.closeStartArrow();">Close</a>

<div id="start-arrow" [ngClass]="{active: uiLayoutService.startArrowIsVisible}">
    ... Some pretty content here ...
</div>

navigation-cart.component.html

<a (click)="uiLayoutService.openStartArrow();">Open</a>
<a (click)="uiLayoutService.closeStartArrow();">Close</a>
... Some other content...

Here's what's troubling me:

  • If I click on Open and Close links from within <start-arrow> it all works just fine. The template gets updated and <div id="start-arrow"> get's closed and or reopened as expected. The console shows these actions running just fine.
  • If I click on Open and Close links from within <navigation-cart> the console fires the messages, I see the startArrowIsVisible value getting updated, but no template update happens in <start-arrow> . [ngClass]="{active: uiLayoutService.startArrowIsVisible} just doesn't seem to trigger the template update. I guess that this is because of optimisations done in order to prevent rendering the layout for all the app needlessly. How can I trigger the layout refresh in this situation?

I assume you provide the UiLayoutService service multiple times and when click, the value is updated on a different instance than the one the components view is bound to. Angular DI creates a new instance per provider. If you want a single instance to be shared among your application, just share it once on the root component (or another common parent)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM