Wzywam router.navigate
na tej samej stronie z niektórymi parametrami ciągu zapytania. W tym przypadku ngOnInit()
nie dzwoni. Czy jest to ustawienie domyślne, czy muszę dodać coś jeszcze?
Wzywam router.navigate
na tej samej stronie z niektórymi parametrami ciągu zapytania. W tym przypadku ngOnInit()
nie dzwoni. Czy jest to ustawienie domyślne, czy muszę dodać coś jeszcze?
Odpowiedzi:
Możesz wstrzyknąć ActivatedRoute
i subskrybowaćparams
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
Router niszczy i odtwarza komponent tylko wtedy, gdy przechodzi do innej trasy. Gdy aktualizowane są tylko parametry trasy lub parametry zapytania, ale trasa jest taka sama, komponent nie zostanie zniszczony i odtworzony.
Alternatywnym sposobem wymuszenia ponownego utworzenia komponentu jest użycie niestandardowej strategii ponownego wykorzystania. Zobacz też Angular2 router 2.0.0 nie przeładowuje komponentów, gdy ten sam adres URL jest ładowany z różnymi parametrami? (wydaje się, że nie ma jeszcze wielu dostępnych informacji, jak to wdrożyć)
Możesz dostosować strategię reuseStrategy na routerze.
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
onSameUrlNavigation: 'reload'
do obiektu config tak: RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})
. Nie mogę jednak mówić o innych wersjach Angulara.
Użyłem następujących i zadziałało.
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
?
Czy prawdopodobnie potrzebujesz przeładować stronę? Oto moje rozwiązanie: zmieniłem @NgModule (w pliku app-routing.module.ts w moim przypadku):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
W Twojej metodzie nawigacji
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
Miałem ten sam problem, dodatkowo dostałem ostrzeżenie:
did you forget to call `ngZone.run()`
Ta witryna zapewniła najlepsze rozwiązanie:
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]));
}
Ten problem prawdopodobnie wynika z faktu, że nie przerywasz subskrypcji za pomocą ngOnDestroy. Oto jak to zrobić.
Wprowadź następujący import subskrypcji rxjs.
import { Subscription } from 'rxjs/Subscription';
Dodaj OnDestory do swojego importu Angular Core.
import { Component, OnDestroy, OnInit } from '@angular/core';
Dodaj OnDestory do swojej klasy eksportu.
export class DisplayComponent implements OnInit, OnDestroy {
Utwórz właściwość obiektu o wartości Subskrypcja z rxjs w ramach klasy eksportu dla każdej subskrypcji składnika.
myVariable: Subscription;
Ustaw wartość swojej subskrypcji na MyVariable: Subscriptions.
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
Następnie tuż pod ngOninit umieść haczyk cyklu życia ngOnDestory () i umieść oświadczenie o rezygnacji z subskrypcji dla subskrypcji. Jeśli masz wiele, dodaj więcej
ngOnDestroy() {
this.myVariable.unsubscribe();
}
ngOnDestory
zamiast ngOnDestroy
siebie ;-)
Oto zbiór najlepszych pomysłów na tej stronie wraz z dodatkowymi informacjami
Rozwiązanie 1 - Użyj subskrypcji params:
Samouczek: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters
Dokumenty: https://angular.io/api/router/ActivatedRoute#params
W każdym z komponentów routingu, które używają zmiennych param, znajdują się następujące elementy:
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();
}
}
Niektóre typowe problemy z tym kodem polegają na tym, że subskrypcje są asynchroniczne i mogą być trudniejsze do rozwiązania. Nie możesz też zapomnieć o anulowaniu subskrypcji na ngOnDestroy, bo inaczej mogą się zdarzyć złe rzeczy.
Dobrze, że jest to najbardziej udokumentowany i powszechny sposób rozwiązania tego problemu. W ten sposób można również poprawić wydajność, ponieważ ponownie używasz szablonu zamiast niszczyć i odtwarzać za każdym razem, gdy odwiedzasz stronę.
Rozwiązanie 2 - shouldReuseRoute / onSameUrlNavigation:
Dokumenty: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation
Dokumenty: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute
Dokumenty: https://angular.io/api/router/ActivatedRouteSnapshot#params
Znajdź RouterModule.forRoot
lokalizację w projekcie (zwykle w app-routing.module.ts lub app.module.ts):
const routes: Routes = [
// ...
];
// ...
@NgModule({
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload'
})],
exports: [RouterModule]
})
Następnie w AppComponent dodaj następujące elementy:
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;
};
// ...
}
// ...
}
Wreszcie, w komponentach routingu możesz teraz obsługiwać zmienne param w następujący sposób:
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;
// ...
}
// ...
}
Typowe problemy z tym rozwiązaniem polegają na tym, że nie jest powszechne. Zmieniasz również domyślne zachowanie frameworka Angular, dzięki czemu możesz napotkać problemy, na które normalnie nie napotkaliby ludzie.
Dobrze, że cały twój kod jest synchroniczny i łatwiejszy do zrozumienia.
Rozważ przeniesienie kodu z ngOnInit do ngAfterViewInit. Ten ostatni wydaje się być wywoływany w nawigacji routera i powinien pomóc w tym przypadku.
Jeśli chcesz, aby router nawigował po tej samej stronie i chcesz wywołać ngOnInit (), robisz to, np.
this.router.navigate (['kategoria / lista', kategoria]) .then (() => window.location.reload ());