Can't reload/refresh active route

2020-01-27 05:50发布

问题:

I have recently updated to the new RC3 and Router3alpha and it seems some things have changed.

I noticed that a click on the link of an active route does no longer result in the component to be reloaded. How do I achieve this behaviour with the new router3?

My link looks like

<a [routerLink]="['/link1']">Link1</a>

And to test I simply used a random number in ngOnInit:

export class LinkoneComponent implements OnInit 
{

    public foo: number;
    constructor() {}

    ngOnInit() 
    {
        this.foo = Math.floor(Math.random() * 100) + 1;
    }

}

It works just fine when switiching between routes, but a click on the currently active route does not result in a reload of the component.

回答1:

This is currently not supported. If only parameter values change but the route stays the same the component is not re-created.

See also https://github.com/angular/angular/issues/9811

You can subscribe to params to get notified when the params change to re-initialize the component instance.

See also https://stackoverflow.com/a/38560010/217408



回答2:

Angular 2-4 current route reload hack

For me, using this method works:

onRefresh() {
  this.router.routeReuseStrategy.shouldReuseRoute = function(){return false;};

  let currentUrl = this.router.url + '?';

  this.router.navigateByUrl(currentUrl)
    .then(() => {
      this.router.navigated = false;
      this.router.navigate([this.router.url]);
    });
  }

You can attach this method to a click event on the current component to reload it.



回答3:

As of Angular 5.1 this can now be done by using the onSameUrlNavigation configuration option as part of the built-in Angular router. It's fairly straightforward to set-up and get going although not obvious from the documentation.

The first thing you will need to do is set the option within your app.routing.ts if you have one or the file where your app routing is configured.

There are two possible values for onSameUrlNavigation 'reload' or false. The default value is false which causes nothing to happen when the router is asked to navigate to the active route. We want to set this value to reload. It is worth noting reload does not actually do the work of reloading the route, it only re-triggers events on the router that we then need to hook into.

@NgModule({
  imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})],
  exports: [RouterModule],
})

To determine when those events are actually fired, you need to specify the runGuardsAndResolvers configuration option on your route. This can take three values...

paramsChange - only fire when route params have changed e.g. where the id in /user/:id changes

paramsOrQueryParamsChange - fire when a route param changes or a query param changes. e.g. the id or the limit property change in /user/:id/invites?limit=10

always - Always fire when the route is navigated

We want to specify always in this case. An example route is shown below.

export const routes: Routes = [
  {
    path: 'invites',
    component: InviteComponent,
    children: [
      {
        path: '',
        loadChildren: './pages/invites/invites.module#InvitesModule',
      },
    ],
    canActivate: [AuthenticationGuard],
    runGuardsAndResolvers: 'always',
  }
]

That is your router configured. The next step is to actually handle the events within one of your components. You will need to import the Router into your component and then hook into the events. In this example, I have hooked into the NavigationEnd event which is fired once the router has completed its navigation from one route to the next. Due to the way we have configured the app, this will now fire even if you try to navigate to the current route.

export class InviteComponent implements OnInit {
  constructor(
    // ... your declarations here
    private router: Router,
  ) {
    // subscribe to the router events
    this.router.events.subscribe((e: any) => {
      // If it is a NavigationEnd event re-initalise the component
      if (e instanceof NavigationEnd) {
        this.initialiseInvites();
      }
    });
  }

  initialiseInvites() {
    // Set default values and re-fetch any data you need.
  }
}

The heavy lifting goes into the initialiseInvites() method, this is where you reset properties to their default values and fetch data from services to get the component back to its initial state.

You need to repeat this pattern across each component that you want to be able to reload when clicked or refresh through some form of refresh button, being sure to add the runGuardsAndResolvers option to each route in the routing file.



回答4:

this worked for me, taken from this:

redirectTo(uri) {
    this.router.navigateByUrl('/', {skipLocationChange: true}).then(() =>
    this.router.navigate([uri]));
  }

now you can use like: this.redirectTo(this.router.url);



回答5:

For Angular 2 rc7 - router 3.0

Change base url in index.html to <script>document.write('<base href="/" />');</script>



回答6:

This is the best hack that I've been able to come up to get around this annoying problem:

    var currentUrl = this.router.url;
    var refreshUrl = currentUrl.indexOf('someRoute') > -1 ? '/someOtherRoute' : '/someRoute';
    this.router.navigateByUrl(refreshUrl).then(() => this.router.navigateByUrl(currentUrl));

This works, but it's still a hack and I hate that the Angular team didn't provide a reload() method



回答7:

if (currentUrl.indexOf('/settings') > -1) {
    this.router.navigateByUrl('/communication').then(() => this.router.navigateByUrl('/settings'));
} else {
    this.router.navigate(['/settings']);
}


回答8:

If you really need to trick the Router into reloading the component on each routerLink click, you can use the following code in your Component

constructor(private router: Router){ // override the route reuse strategy this.router.routeReuseStrategy.shouldReuseRoute = function(){ return false; }

 this.router.events.subscribe((evt) => {
    if (evt instanceof NavigationEnd) {
       // trick the Router into believing it's last link wasn't previously loaded
       this.router.navigated = false;
       // if you need to scroll back to top, here is the right place
       window.scrollTo(0, 0);
    }
});

} Hope this helps



回答9:

In my modest opinion you could use the window.location.reload() in typescript. This way can be easy and secure because is a part of the browser functionalities.