typescript - Hvordan laste den nåværende ruten på nytt med Angular 2-routeren


Jeg bruker Angular 2 med hashlocation-strategi.

Komponenten lastes med den ruten:

"departments/:id/employees"

Så langt så bra.

Etter at jeg har gjort en vellykket batch-lagring av flere redigerte tabellrader, ønsker jeg å laste gjeldende rute-URL på nytt via:

this.router.navigate([`departments/${this.id}/employees`]);

Men ingenting skjer, hvorfor?

Svar #1

Lag en funksjon i kontrolleren som videresender til den forventede ruten slik:

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

Så bruker du det slik

this.redirectTo('//place your uri here');

Denne funksjonen vil omdirigere til en midlertidig rute og raskt returnere til destinasjonsruten uten at brukeren merker det.

Svar #2

Dette kan nå gjøres i Angular 5.1 ved å bruke onSameUrlNavigation-egenskapen i Router-konfigurasjonen.

Jeg har lagt til en blogg som forklarer hvordan her, men hovedpoenget er som følger

https://medium.com/engineering-on-the-incline/reloading-current-route-on-click-angular-5-1a1bfc740ab2

I ruterkonfigurasjonen din aktiver onSameUrlNavigation-alternativet, og sett det til 'reload'. Dette får Ruteren til å starte en hendelsessyklus når du prøver å navigere til en rute som allerede er aktiv.

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

I rutedefinisjonene dine, sett runGuardsAndResolvers til always. Dette vil fortelle ruteren å alltid starte vaktene og resolver-sykluser, og utløse tilknyttede hendelser.

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

Til slutt, i hver komponent som du ønsker å aktivere opplasting på nytt, må du håndtere hendelsene. Dette kan gjøres ved å importere ruteren, binde seg til hendelsene og kalle en initialiseringsmetode som tilbakestiller komponentens tilstand og henter data på nytt om nødvendig.

export class InviteComponent implements OnInit, OnDestroy {
 navigationSubscription;     

 constructor(
   // … your declarations here
   private router: Router,
 ) {
   // subscribe to the router events. Store the subscription so we can
   // unsubscribe later.
   this.navigationSubscription = 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.
 }

 ngOnDestroy() {
   if (this.navigationSubscription) {
     this.navigationSubscription.unsubscribe();
   }
 }
}

Med alle disse trinnene på plass, bør du ha rutinggjenlasting aktivert.

Svar #3

Jeg bruker denne for Angular 11-prosjektet:

reloadCurrentRoute() {
  const currentUrl = this.router.url;
  this.router.navigateByUrl('/', { skipLocationChange: true }).then(() => {
    this.router.navigate([currentUrl]);
  });
}

PS: Testet og fungerer på alle versjoner over 7.

Svar #4

REDIGER

For nyere versjoner av Angular (5.1+) bruk svaret foreslått av @Simon McClive

Gammelt svar

Jeg fant denne løsningen på en GitHub-funksjonsforespørsel for Angular:

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

this._router.events.subscribe((evt) => {
    if (evt instanceof NavigationEnd) {
        this._router.navigated = false;
        window.scrollTo(0, 0);
    }
});

Jeg prøvde å legge dette til i min app.component.ts ngOnInit-funksjon, og det fungerte absolutt. Alle videre klikk på samme lenke laster nå komponenten og dataene på nytt.

Lenke til original GitHub-funksjonsforespørsel

Kreditten går til mihaicux2 på GitHub.

Jeg testet dette på versjon 4.0.0-rc.3 med import { Router, NavigationEnd } from '@angular/router';

Svar #5

Dette er hva jeg gjorde med Angular 12. Jeg er ikke sikker på om dette fungerer i versjoner under 9.

Du må ringe dette når du trenger å laste på nytt.

 this.router.navigate([], {
    skipLocationChange: true,
    queryParamsHandling: 'merge' //== if you need to keep queryParams
  })

Router forRoot må ha SameUrlNavigation satt til 'reload'

 RouterModule.forRoot(appRoutes, {
  // ..
  onSameUrlNavigation: 'reload',
  // ..
})

Og hver rute du har må ha runGuardsAndResolvers satt til 'always'

{
    path: '',
    data: {},
    runGuardsAndResolvers: 'always'
},

Svar #6

Hvis din navigate() ikke endrer URL-en som allerede vises på adressefeltet i nettleseren din, har ruteren ingenting å gjøre. Det er ikke ruterens jobb å oppdatere dataene. Hvis du vil oppdatere dataene, opprett en tjeneste som injiseres i komponenten og kall load-funksjonen på tjenesten. Hvis de nye dataene blir hentet, vil de oppdatere visningen via bindinger.

Svar #7

Dette fungerer for meg som en sjarm

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

Svar #8

Litt tricky: bruk samme sti med noen dummy-parametere. For eksempel-

refresh(){
  this.router.navigate(["/same/route/path?refresh=1"]);
}

Svar #9

Angular 2-4 ruteoppdateringshack

For meg fungerer det å bruke denne metoden inne i en rotkomponent (komponent, som finnes på hvilken som helst rute):

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]);
    });
  }

Svar #10

Ved endring av parameter vil ikke siden lastes på nytt. Dette er en veldig god funksjon. Det er ikke nødvendig å laste siden på nytt, men vi bør endre verdien på komponenten. paramChange-metoden vil bli kalt ved URL-endring. Så vi kan oppdatere komponentdataene.

/product/: id / details

import { ActivatedRoute, Params, Router } from ‘@angular/router’;

export class ProductDetailsComponent implements OnInit {

constructor(private route: ActivatedRoute, private router: Router) {
    this.route.params.subscribe(params => {
        this.paramsChange(params.id);
    });
}

// Call this method on page change

ngOnInit() {

}

// Call this method on change of the param
paramsChange(id) {

}

Relaterte artikler