I have an Aurelia application where the user can select the company they\'re currently \"working on\". Every page in the app is dependent on the currently selected company,
This does not answer your exact question which is how to force a reload of the current view, but have you considered adding the current company identifier to your route(s)? This will solve your problem and make your routes bookmarkable: ie: /#/company1/view1
and /#/company2/view1
. When you change the company in the drop-down you call router.navigate()
with the new route and the new view will be loaded/refreshed.
To answer your exact question, I tested the router.navigate
options: router.navigate('myroute', {replace:true, trigger:true})
and none of them force a reload of the view if the right view is already loaded. By appending ?ramdomNumber
to your route name you can force a reactivation of the view.
While not officially supported, there are a variety of hacks suggestions in a relevant GitHub issue asking for this very functionality.
The one I got to work that does not involve updating aurelia's source code nor adding superfluous data to the route is to set the activationStrategy on all of my routes to be invokeLifecycle
instead of the default, like so:
import { activationStrategy } from 'aurelia-router';
export class App {
configureRouter(config, router) {
config.map([
{
route: ['', 'home'],
name: 'home',
moduleId: 'home/index',
activationStrategy: activationStrategy.invokeLifecycle
},
{
route: 'users',
name: 'users',
moduleId: 'users/index',
nav: true,
activationStrategy: activationStrategy.invokeLifecycle
},
... etc ...
]);
}
}
This makes it so the route's activate()
method will run as you expect when the view model is reloaded. Then, in the code that initiates the reload, I do the following:
this.router.navigateToRoute(
this.router.currentInstruction.config.name,
this.router.currentInstruction.params,
{ replace: true }
);
Here is a simple solution to refresh the page:
in aurelia-history-browser.js, added a check in updateHash()
and if the new _href is equal to the old then reload the page from the cache (not the server).
Then, to refresh the page you just need to use the existing options:
router.navigateToRoute('watch', {}, { replace: true, trigger: true });
The updated code is copied below:
function updateHash(location, fragment, replace) {
if (replace) {
var _href = location.href.replace(/(javascript:|#).*$/, '') + '#' + fragment;
if (_href == location.href)
location.reload(false);
else
location.replace(_href);
} else {
location.hash = '#' + fragment;
}
}
Better answer:
this.router.navigateToRoute(
this.router.currentInstruction.config.name,
{
...this.router.currentInstruction.params,
reload: Number(this.router.currentInstruction.queryParams.reload || 0) + 1,
},
{ trigger: true },
);
The navigateToRoute()
takes 3 parameters:
trigger: true
option forces an activationStrategy: invokeLifecycle
on this specific routing instruction without the need to set this option in the viewModel or routeConfig for normal routing.