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.
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
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.
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.
Für Angular 2 RC7 - Router 3.0
Ändern Sie die Basis-URL in index.html in <script>document.write('<base href="/" />');</script>
.
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)
;
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
if (currentUrl.indexOf('/settings') > -1) {
this.router.navigateByUrl('/communication').then(() => this.router.navigateByUrl('/settings'));
} else {
this.router.navigate(['/settings']);
}