Reputation: 12838
I'm trying to add a class
to the html
element when Aurelia is navigating to a new route so that I can style the page differently when it's loading.
My current solution is to add the class to the main
element because that's part of my View and so it "just works", like this:
import {inject} from 'aurelia-framework';
import {Router} from 'aurelia-router';
@inject(Router)
export class App {
constructor (router) {
this.router = router;
}
}
And then in my view I simply do:
<main class="${router.isNavigating ? 'loading' : ''}">
<router-view></router-view>
</main>
But, like I mentioned, I would prefer to add the loading
class to the html
element instead (so that I can style every single decendant on the page). Since the html
element is not part of my view I can't accomplish this the same way, but instead I need to document.documentElement.classList.add('loading')
whenever router.isNavigating
is true.
So my question is; how can I accomplish this? I know aurelia supports propertyChanged
methods but I'm not sure how it works when it's a nested property like router.isNavigating
, routerIsNavigatingChanged()
does not work. I've also tried @computedFrom(router)
and variants of that but can't get it to work.
Upvotes: 2
Views: 1068
Reputation: 11990
Another solution could be using the BindingEngine, but I think that EventAggregator is a better solution. I'm posting this here just for your curiosity.
import {BindingEngine} from 'aurelia-binding';
export class App {
static inject = [BindingEngine];
constructor(bindingEngine) {
this.bindingEngine = bindingEngine;
}
configureRouter(config, router) {
//...
this.router = router;
}
attached() {
this.navigationSubs = this.bindingEngine
.propertyObserver(this.router, 'isNavigating')
.subscribe(this.isNavigationChanged);
}
detached() {
this.navigationSubs.dispose();
}
isNavigationChanged(newValue, oldValue) {
if (newValue) {
document.documentElement.classList.add('loading');
} else {
document.documentElement.classList.remove('loading');
}
}
}
In addition, I'm not sure if setting class
of the html
is good idea.
Upvotes: 4
Reputation: 12838
Ok so I ended up solving this using the EventAggregator
instead;
this.ea.subscribe('router:navigation:processing', event => {
document.documentElement.classList.add('loading');
});
this.ea.subscribe('router:navigation:success', event => {
document.documentElement.classList.remove('loading');
});
I'm not sure it's the best solution but it seems to work. Would still like to know whether it's possible to do @computedFrom('router.isNavigating')
because trying that throws errors.
Upvotes: 2