Ich rufe router.navigate
auf derselben Seite mit einigen Abfragezeichenfolgenparametern auf. In diesem Fall ngOnInit()
ruft nicht an. Ist es standardmäßig oder muss ich noch etwas hinzufügen?
Ich rufe router.navigate
auf derselben Seite mit einigen Abfragezeichenfolgenparametern auf. In diesem Fall ngOnInit()
ruft nicht an. Ist es standardmäßig oder muss ich noch etwas hinzufügen?
Antworten:
Sie können das injizieren ActivatedRoute
und abonnierenparams
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
Der Router zerstört und erstellt die Komponente nur neu, wenn er zu einer anderen Route navigiert. Wenn nur Routenparameter oder Abfrageparameter aktualisiert werden, die Route jedoch dieselbe ist, wird die Komponente nicht zerstört und neu erstellt.
Eine alternative Möglichkeit, die Neuerstellung der Komponente zu erzwingen, ist die Verwendung einer benutzerdefinierten Wiederverwendungsstrategie. Siehe auch Angular2 Router 2.0.0 lädt keine Komponenten neu, wenn dieselbe URL mit unterschiedlichen Parametern geladen wurde. (Es scheinen noch nicht viele Informationen verfügbar zu sein, wie man es implementiert)
Sie können die reuseStrategy auf dem Router anpassen.
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
onSameUrlNavigation: 'reload'
das Konfigurationsobjekt wie folgt hinzufügen müssen : RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})
. Kann aber nicht für andere Angular-Versionen sprechen.
Ich habe folgendes verwendet und es hat funktioniert.
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
?
Benötigen Sie wahrscheinlich eine Seite zum Neuladen? Dies ist meine Lösung: Ich habe das @ NgModule geändert ( in meinem Fall in der Datei app-routing.module.ts ):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
NgOnInit
würde einmal aufgerufen, wenn eine Instanz erstellt wird. Für die gleiche Instanz NgOnInit
wird nicht wieder aufgerufen. Um es aufzurufen, muss die erstellte Instanz zerstört werden.
Auf Ihrer Navigationsmethode,
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
Ich hatte das gleiche Problem, zusätzlich bekam ich die Warnung:
did you forget to call `ngZone.run()`
Diese Seite bot die beste Lösung:
import { Router } from '@angular/router';
import { NgZone } from '@angular/core';
...
constructor(
private ngZone:NgZone,
private _router: Router
){ }
redirect(to) {
// call with ngZone, so that ngOnOnit of component is called
this.ngZone.run(()=>this._router.navigate([to]));
}
Dieses Problem ist wahrscheinlich darauf zurückzuführen, dass Sie Ihre Abonnements nicht mit ngOnDestroy kündigen. Hier erfahren Sie, wie Sie es schaffen.
Bringen Sie den folgenden rxjs-Abonnementimport mit.
import { Subscription } from 'rxjs/Subscription';
Fügen Sie Ihrem Angular Core-Import OnDestory hinzu.
import { Component, OnDestroy, OnInit } from '@angular/core';
Fügen Sie Ihrer Exportklasse OnDestory hinzu.
export class DisplayComponent implements OnInit, OnDestroy {
Erstellen Sie für jedes Abonnement der Komponente eine Objekteigenschaft mit dem Wert Subscription von rxjs unter Ihrer Exportklasse.
myVariable: Subscription;
Stellen Sie den Wert Ihres Abonnements auf MyVariable: Subscriptions ein.
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
Platzieren Sie dann direkt unter ngOninit den Lebenszyklus-Hook ngOnDestory () und geben Sie Ihre Abmeldeerklärung für Ihr Abonnement ein. Wenn Sie mehrere haben, fügen Sie weitere hinzu
ngOnDestroy() {
this.myVariable.unsubscribe();
}
ngOnDestory
anstatt ngOnDestroy
mich selbst
Hier finden Sie eine Sammlung der besten Ideen auf dieser Seite mit weiteren Informationen
Lösung 1 - Verwenden Sie das params-Abonnement:
Tutorial: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters
Dokumente: https://angular.io/api/router/ActivatedRoute#params
In jeder Ihrer Routing-Komponenten, die Parametervariablen verwenden, ist Folgendes enthalten:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
// ...
@Component({
// ...
})
export class MyComponent implements OnInit, OnDestroy {
paramsSub: Subscription;
// ...
constructor(activeRoute: ActivatedRoute) {
}
public ngOnInit(): void {
// ...
this.paramsSub = this.activeRoute.params.subscribe(val => {
// Handle param values here
});
// ...
}
// ...
public ngOnDestroy(): void {
// Prevent memory leaks
this.paramsSub.unsubscribe();
}
}
Einige häufige Probleme mit diesem Code sind, dass Abonnements asynchron sind und schwieriger zu handhaben sind. Sie können auch nicht vergessen, sich bei ngOnDestroy abzumelden, da sonst schlimme Dinge passieren können.
Gut ist, dass dies der am besten dokumentierte und gebräuchlichste Weg ist, um dieses Problem zu lösen. Auf diese Weise wird auch die Leistung verbessert, da Sie die Vorlage wiederverwenden, anstatt sie bei jedem Besuch einer Seite zu zerstören und neu zu erstellen.
Lösung 2 - shouldReuseRoute / onSameUrlNavigation:
Dokumente: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation
Dokumente: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute
Dokumente: https://angular.io/api/router/ActivatedRouteSnapshot#params
Finden Sie heraus, wo RouterModule.forRoot
sich Ihr Projekt befindet (normalerweise in app-routing.module.ts oder app.module.ts):
const routes: Routes = [
// ...
];
// ...
@NgModule({
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload'
})],
exports: [RouterModule]
})
Fügen Sie dann in AppComponent Folgendes hinzu:
import { Component, OnInit} from '@angular/core';
import { Router } from '@angular/router';
// ...
@Component({
// ...
})
export class AppComponent implements OnInit {
constructor(private router: Router) {
}
ngOnInit() {
// Allows for ngOnInit to be called on routing to the same routing Component since we will never reuse a route
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
// ...
}
// ...
}
Zuletzt können Sie in Ihren Routing-Komponenten jetzt folgende Parametervariablen verarbeiten:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
// ...
@Component({
// ...
})
export class MyComponent implements OnInit {
// ...
constructor(activeRoute: ActivatedRoute) {
}
public ngOnInit(): void {
// Handle params
const params = +this.activeRoute.snapshot.params;
// ...
}
// ...
}
Häufige Probleme mit dieser Lösung sind, dass es nicht häufig ist. Außerdem ändern Sie das Standardverhalten des Angular-Frameworks, sodass Sie auf Probleme stoßen können, auf die Menschen normalerweise nicht stoßen würden.
Gut ist, dass Ihr gesamter Code synchron und leichter zu verstehen ist.
Verschieben Sie den Code, den Sie in ngOnInit hatten, in ngAfterViewInit. Letzteres scheint in der Routernavigation aufgerufen zu werden und sollte Ihnen in diesem Fall helfen.
Wenn Sie mit dem Router auf derselben Seite navigieren und ngOnInit () aufrufen möchten, gefällt Ihnen dies z.
this.router.navigate (['category / list', category]) .then (() => window.location.reload ());