Estoy llamando router.navigate
en la misma página con algunos parámetros de cadena de consulta. En este caso, ngOnInit()
no llama. ¿Es por defecto o necesito agregar algo más?
Estoy llamando router.navigate
en la misma página con algunos parámetros de cadena de consulta. En este caso, ngOnInit()
no llama. ¿Es por defecto o necesito agregar algo más?
Respuestas:
Puede inyectar ActivatedRoute
y suscribirse aparams
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
El enrutador solo destruye y recrea el componente cuando navega a una ruta diferente. Cuando solo se actualizan los parámetros de ruta o los parámetros de consulta, pero la ruta es la misma, el componente no se destruirá ni se volverá a crear.
Una forma alternativa de forzar la recreación del componente es utilizar una estrategia de reutilización personalizada. Consulte también el enrutador Angular2 2.0.0 que no recarga componentes cuando la misma URL se carga con diferentes parámetros. (no parece haber mucha información disponible todavía sobre cómo implementarlo)
Puede ajustar la estrategia de reutilización en el enrutador.
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
onSameUrlNavigation: 'reload'
al objeto de configuración de este modo: RouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})
. Sin embargo, no puedo hablar de ninguna otra versión de Angular.
He usado lo siguiente y funcionó.
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
?
¿Probablemente necesita volver a cargar la página? Esta es mi solución: he cambiado el @NgModule (en el archivo app-routing.module.ts en mi caso):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
En su método de navegación,
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});
Tuve el mismo problema, además recibí la advertencia:
did you forget to call `ngZone.run()`
Este sitio proporcionó la mejor solución:
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]));
}
Es probable que este problema se deba al hecho de que no está cancelando sus suscripciones usando ngOnDestroy. A continuación se explica cómo terminar.
Traiga la siguiente importación de suscripción rxjs.
import { Subscription } from 'rxjs/Subscription';
Agregue OnDestory a su importación de Angular Core.
import { Component, OnDestroy, OnInit } from '@angular/core';
Agregue OnDestory a su clase de exportación.
export class DisplayComponent implements OnInit, OnDestroy {
Cree una propiedad de objeto con un valor de Suscripción de rxjs en su clase de exportación para cada suscripción en el componente.
myVariable: Subscription;
Establezca el valor de su suscripción a MyVariable: Subscriptions.
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
Luego, justo debajo de ngOninit, coloque el enlace del ciclo de vida de ngOnDestory () e ingrese su declaración de cancelación de suscripción para su suscripción. Si tiene varios, agregue más
ngOnDestroy() {
this.myVariable.unsubscribe();
}
ngOnDestory
en ngOnDestroy
mi lugar también ;-)
Cree una ruta diferente para el mismo componente en la matriz de rutas.
rutas const: Rutas = [{ruta: "aplicación", componente: MiComponente}, {ruta: "recarga de la aplicación", componente: MiComponente}];
Si la URL actual es "aplicación", navegue usando "recargar aplicación" y viceversa.
Aquí hay una colección de las mejores ideas en esta página con más información.
Solución 1 - Utilice la suscripción de params:
Tutorial: https://angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters
Documentos: https://angular.io/api/router/ActivatedRoute#params
En cada uno de sus componentes de enrutamiento que usan variables param, se incluyen lo siguiente:
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();
}
}
Algunos problemas comunes con este código es que las suscripciones son asincrónicas y pueden ser más difíciles de manejar. Además, no puede olvidarse de darse de baja en ngOnDestroy o pueden suceder cosas malas.
Lo bueno es que esta es la forma más documentada y común de manejar este problema. También hay una mejora del rendimiento al hacerlo de esta manera, ya que está reutilizando la plantilla en lugar de destruirla y recrearla cada vez que visita una página.
Solución 2 - shouldReuseRoute / onSameUrlNavigation:
Documentos: https://angular.io/api/router/ExtraOptions#onSameUrlNavigation
Documentos: https://angular.io/api/router/RouteReuseStrategy#shouldReuseRoute
Documentos: https://angular.io/api/router/ActivatedRouteSnapshot#params
Encuentre dónde RouterModule.forRoot
se encuentra en su proyecto (normalmente se encuentra en app-routing.module.ts o app.module.ts):
const routes: Routes = [
// ...
];
// ...
@NgModule({
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload'
})],
exports: [RouterModule]
})
Luego, en AppComponent agregue lo siguiente:
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;
};
// ...
}
// ...
}
Por último, en sus componentes de enrutamiento ahora puede manejar variables de parámetros como esta:
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;
// ...
}
// ...
}
Los problemas comunes con esta solución es que no es común. Además, está cambiando el comportamiento predeterminado del marco angular, por lo que puede encontrarse con problemas con los que la gente normalmente no se encontraría.
Lo bueno es que todo su código es sincrónico y más fácil de entender.
Considere mover el código que tenía en ngOnInit a ngAfterViewInit. Este último parece ser llamado en la navegación del enrutador y debería ayudarlo en este caso.
Cuando desea navegar en el enrutador en la misma página y desea llamar a ngOnInit (), entonces lo hace así, por ejemplo,
this.router.navigate (['categoría / lista', categoría]). then (() => window.location.reload ());