Ivan Ivan - 1 month ago 14
TypeScript Question

Angular 2.0.0 [hidden] doesn't run in some cases

I've layout with

[hidden]
:

<main id="content" class="content view-animate fade-up" role="main">
<div [hidden]="!preloader.isLoading">
<img class="absolute-center" src="/assets/img/cube.svg" alt="Loading..."/>
</div>
<div [hidden]="preloader.isLoading">
<router-outlet></router-outlet>
</div>
</main>


I've service to handle this:

export class PreloaderService {
private _isLoading: boolean = false;
constructor(router:Router) {
router.events.subscribe((event) => {
console.log('event',event);
if(event instanceof NavigationStart) {
this._isLoading = true;
}
if(event instanceof NavigationCancel || event instanceof NavigationError || event instanceof NavigationEnd ) {
this._isLoading = false;
}
});
}
get isLoading() {
return this._isLoading;
}
}


Problem: when I'm logging in with Facebook account, I see loader, then my target page. If I logging out right after that, and log in with FB again,
NavigationEnd
event fired, value of
preloader.isLoading
changed to
false
, but loading picture still visible. If I click something(in menu near page area for example) - page became visible and loader dissapear.
If I reload page after logging out, then page loading will processed normally.

Answer

This sounds like some callback runs outside Angulars zone.

export class PreloaderService {

    private _isLoading: boolean = false;

    constructor(router:Router, cdRef:ChangeDetectorRef) { // <<<=== modified
        router.events.subscribe((event) => {
            console.log('event',event);
            if(event instanceof NavigationStart) {
                this._isLoading = true;
                cdRef.detectChanges(); // <<<=== added
            }
            if(event instanceof NavigationCancel || event instanceof NavigationError || event instanceof NavigationEnd ) {
                this._isLoading = false;
                cdRef.detectChanges(); // <<<=== added
            }
        });
    }
    get isLoading() {
        return this._isLoading;
    }
}

It's better to use zone.run() where the callback calls Angular2 code outside the zone but that code is not contained in your question.

Above code should at least work to verify that my assumption is correct.