Reload current page in Aurelia
Asked Answered
N

4

20

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, and the user can select a new company from a drop-down menu. The drop-down is a component sitting on the nav-bar.

What I'd like is to have that component reload the current page on the change.delegate handler without restarting the app. So setting window.location.href is out of the question.

Is there a way to force the aurelia Router to reload the current route/page?

The alternative would be to use the EventAggregator to signal a company change throughout the app, but that would require either subscribing to that event on every page or having every page inherit from a base class that subscribes to that event, but these are much more involved options.

Nonfulfillment answered 9/8, 2016 at 8:27 Comment(0)
A
10

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.

Aten answered 9/8, 2016 at 16:39 Comment(2)
I had actually tried appending the name of the company to the routes (/dashboard/company1) instead of using a random number, but that didn't work... And now I realize that it's because I needed to define the route "dashboard/:company" :/Nonfulfillment
That would have worked with ? as in /dashboard?company1 not /.Aten
S
15

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 }
);
Seclusion answered 16/1, 2017 at 19:47 Comment(4)
Interesting... I'll give it a go!Nonfulfillment
You're my hero, this is perfect!Afterheat
Best answer thanks! would have saved me just a few mins if you would have let me know i can import {activationStrategy} from 'aurelia-router'Dextrorotation
Works really well but I had to replace this.router.currentInstruction.params with this.router.currentInstruction.queryParams.Gefen
A
10

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.

Aten answered 9/8, 2016 at 16:39 Comment(2)
I had actually tried appending the name of the company to the routes (/dashboard/company1) instead of using a random number, but that didn't work... And now I realize that it's because I needed to define the route "dashboard/:company" :/Nonfulfillment
That would have worked with ? as in /dashboard?company1 not /.Aten
W
1

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;
    }
  }
Wesleyanism answered 24/8, 2016 at 21:42 Comment(0)
U
1

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:

  1. Name of route: (get from current instruction)
  2. Route parameters: (get from current instruction and add an incremental reload to change the route; easiest way to make the router actually navigate)
  3. Options: The 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.
Ulphi answered 30/3, 2018 at 1:30 Comment(1)
This looks like the most elegant solution, but I'm not having luck getting it to work. The "reload" query parameter appends to the URL properly, but the "trigger" never seems to occur.Gerdagerdeen

© 2022 - 2024 — McMap. All rights reserved.