webentwicklung-frage-antwort-db.com.de

Aktive Route kann nicht neu geladen/aktualisiert werden

Ich habe kürzlich ein Update auf die neue RC3 und Router3alpha durchgeführt und es scheint, dass sich einige Dinge geändert haben.

Mir ist aufgefallen, dass ein Klick auf den Link einer aktiven Route nicht mehr dazu führt, dass die Komponente neu geladen wird. Wie erreiche ich dieses Verhalten mit dem neuen Router3?

Mein Link sieht so aus

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

Und zum Testen habe ich einfach eine Zufallszahl in ngOnInit verwendet:

export class LinkoneComponent implements OnInit 
{

    public foo: number;
    constructor() {}

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

}

Beim Umschalten zwischen den Routen funktioniert das problemlos, aber ein Klick auf die gerade aktive Route führt nicht zum erneuten Laden der Komponente.

25
TommyF

Dies wird derzeit nicht unterstützt. Wenn sich nur Parameterwerte ändern, die Route jedoch gleich bleibt, wird die Komponente nicht neu erstellt. 

Siehe auch https://github.com/angular/angular/issues/9811

Sie können params abonnieren, um benachrichtigt zu werden, wenn sich die params ändern, um die Komponenteninstanz neu zu initialisieren.

Siehe auch https://stackoverflow.com/a/38560010/217408

15

Angular 2-4 aktuelle Route nachladen Hack

Für mich funktioniert diese Methode:

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

Sie können diese Methode an ein Klickereignis der aktuellen Komponente anhängen, um sie erneut zu laden.

5
indreed

Ab Angular 5.1 ist dies jetzt möglich, indem die Konfigurationsoption onSameUrlNavigation Als Teil des integrierten Angular-Routers verwendet wird. Es ist ziemlich einfach einzurichten und loszulegen, obwohl dies aus der Dokumentation nicht ersichtlich ist.

Als Erstes müssen Sie die Option in Ihrem app.routing.ts einstellen, wenn Sie eine oder die Datei haben, in der Ihr App-Routing konfiguriert ist.

Es gibt zwei mögliche Werte für onSameUrlNavigation 'reload' oder false. Der Standardwert ist false, wodurch nichts passiert, wenn der Router aufgefordert wird, zur aktiven Route zu navigieren. Wir möchten diesen Wert auf reload setzen. Es ist erwähnenswert, dass reload das erneute Laden der Route nicht tatsächlich erledigt, sondern nur Ereignisse auf dem Router erneut auslöst, in die wir uns einwählen müssen. 

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

Um zu bestimmen, wann diese Ereignisse tatsächlich ausgelöst werden, müssen Sie die Konfigurationsoption runGuardsAndResolvers auf Ihrer Route angeben. Dies kann drei Werte annehmen ...

paramsChange - wird nur ausgelöst, wenn sich die Routenparameter geändert haben, z. wo sich die ID in /user/:id ändert

paramsOrQueryParamsChange - wird ausgelöst, wenn sich ein Routenparameter oder ein Abfrageparameter ändert. z.B. id oder limit-Eigenschaft ändern sich in /user/:id/invites?limit=10

always - Immer feuern, wenn auf der Route navigiert wird

Wir möchten in diesem Fall immer angeben. Eine Beispielroute ist unten gezeigt.

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

Das ist dein Router konfiguriert. Der nächste Schritt besteht darin, die Ereignisse in einer Ihrer Komponenten tatsächlich zu behandeln. Sie müssen den Router in Ihre Komponente importieren und sich dann mit den Ereignissen verbinden. In diesem Beispiel habe ich mich an das Ereignis NavigationEnd angeschlossen, das ausgelöst wird, wenn der Router seine Navigation von einer Route zur nächsten abgeschlossen hat. Aufgrund der Art und Weise, wie wir die App konfiguriert haben, wird diese jetzt ausgelöst, auch wenn Sie versuchen, zur aktuellen Route zu navigieren.

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.
  }
}

Das schwere Heben geht in die initialiseInvites()-Methode über. Hier setzen Sie die Eigenschaften auf ihre Standardwerte zurück und rufen Daten von Services ab, um die Komponente in den Ausgangszustand zu versetzen.

Sie müssen dieses Muster für jede Komponente wiederholen, die Sie neu laden möchten, wenn Sie auf diese Schaltfläche klicken oder eine Aktualisierungsschaltfläche verwenden, und stellen Sie sicher, dass die Option runGuardsAndResolvers zu jeder Route in der Routing-Datei hinzugefügt wird.

3
Simon McClive

Für Angular 2 RC7 - Router 3.0

Ändern Sie die Basis-URL in index.html in <script>document.write('<base href="/" />');</script>.

2
supersonic

das hat für mich funktioniert, genommen von this :

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

jetzt können Sie wie folgt verwenden: this.redirectTo(this.router.url);

1
simple_human

Dies ist der beste Hack, den ich rausbringen konnte, um dieses nervige Problem zu umgehen:

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

Das funktioniert, aber es ist immer noch ein Hack und ich hasse es, dass das Angular-Team keine reload()-Methode zur Verfügung gestellt hat

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