pathmatch - Cómo recargar la ruta actual con el enrutador angular 2
routerlink (28)
Estoy usando angular 2 con estrategia de hashlocation.
El componente se carga con esa ruta:
"departments/:id/employees"
Hasta ahora bien.
Después de realizar un guardado por lotes exitoso de varias filas de tablas editadas, quiero volver a cargar la URL de ruta actual a través de:
this.router.navigate([`departments/${this.id}/employees`]);
Pero no pasa nada, ¿por qué?
Cree una función en el controlador que redirija a la ruta esperada así
redirectTo(uri:string){
this.router.navigateByUrl(''/DummyComponent'', {skipLocationChange: true}).then(()=>
this.router.navigate([uri]));}
entonces úsalo así
this.redirectTo(''//place your uri here'');
Esta función redirigirá a una ruta ficticia y volverá rápidamente a la ruta de destino sin que el usuario se dé cuenta.
Creo que esto se ha resuelto (de forma nativa) en Angular 6+; comprobar
Pero esto funciona para una ruta completa (incluye todas las rutas secundarias también)
Si desea apuntar a un solo componente, así es como: use un parámetro de consulta que cambie, para que pueda navegar tantas veces como desee.
En el punto de navegación (clase)
this.router.navigate([''/route''], {
queryParams: { ''refresh'': Date.now() }
});
En el componente que desea "actualizar / recargar"
// . . . Component Class Body
$_route$: Subscription;
constructor (private _route: ActivatedRoute) {}
ngOnInit() {
this.$_route$ = this._route.queryParams.subscribe(params => {
if (params[''refresh'']) {
// Do Something
// Could be calling this.ngOnInit() PS: I Strongly advise against this
}
});
}
ngOnDestroy() {
// Always unsubscribe to prevent memory leak and unexpected behavior
this.$_route$.unsubscribe();
}
// . . . End of Component Class Body
El siguiente código funcionará:
logoFn(url: any) {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
};
this.router.navigate(['''']); or
this.router.navigate([url]);
}
En el cambio de parámetros la página de recarga no sucederá. Esta es una muy buena característica. No es necesario volver a cargar la página, pero debemos cambiar el valor del componente. El método paramChange invocará el cambio de URL. Para que podamos actualizar los datos del componente
/product/: id / details
import { ActivatedRoute, Params, Router } from ‘@angular/router’;
export class ProductDetailsComponent implements OnInit {
constructor(private route: ActivatedRoute, private router: Router) {
this.route.params.subscribe(params => {
this.paramsChange(params.id);
});
}
// Call this method on page change
ngOnInit() {
}
// Call this method on change of the param
paramsChange(id) {
}
En mi caso:
const navigationExtras: NavigationExtras = {
queryParams: { ''param'': val }
};
this.router.navigate([], navigationExtras);
trabajo correcto
Encontré esta solución en una solicitud de función de GitHub para Angular:
this._router.routeReuseStrategy.shouldReuseRoute = function(){
return false;
};
this._router.events.subscribe((evt) => {
if (evt instanceof NavigationEnd) {
this._router.navigated = false;
window.scrollTo(0, 0);
}
});
Intenté agregar esto a mi función
app.component.ts
ngOnInit
, y seguro funcionó.
Todos los clics adicionales en el mismo enlace ahora vuelven a cargar el
component
y los datos.
Enlace a la solicitud de función original de GitHub
El crédito va a mihaicux2 en GitHub.
4.0.0-rc.3
esto en la versión
4.0.0-rc.3
con la
import { Router, NavigationEnd } from ''@angular/router'';
Encontré una solución rápida y directa que no requiere jugar con el funcionamiento interno de angular:
Básicamente: solo cree una ruta alternativa con el mismo módulo de destino y solo alterne entre ellos:
const routes: Routes = [
{
path: ''gesuch'',
loadChildren: ''./sections/gesuch/gesuch.module#GesuchModule''
},
{
path: ''gesuch-neu'',
loadChildren: ''./sections/gesuch/gesuch.module#GesuchModule''
}
];
Y aquí el menú de alternancia:
<ul class="navigation">
<li routerLink="/gesuch-neu" *ngIf="''gesuch'' === getSection()">Gesuch</li>
<li routerLink="/gesuch" *ngIf="''gesuch'' !== getSection()">Gesuch</li>
</ul>
Espero eso ayude :)
Esto ahora se puede hacer en Angular 5.1 utilizando la propiedad
onSameUrlNavigation
de la configuración del enrutador.
He agregado un blog que explica cómo aquí, pero lo esencial es lo siguiente
En la configuración de su enrutador, habilite la opción
onSameUrlNavigation
, configurándola para
''reload''
.
Esto hace que el enrutador active un ciclo de eventos cuando intenta navegar a una ruta que ya está activa.
@ngModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: ''reload''})],
exports: [RouterModule],
})
En sus definiciones de ruta, establezca
runGuardsAndResolvers
en
always
.
Esto le indicará al enrutador que siempre inicie los guardias y los ciclos de resolución, disparando los eventos asociados.
export const routes: Routes = [
{
path: ''invites'',
component: InviteComponent,
children: [
{
path: '''',
loadChildren: ''./pages/invites/invites.module#InvitesModule'',
},
],
canActivate: [AuthenticationGuard],
runGuardsAndResolvers: ''always'',
}
]
Finalmente, en cada componente que le gustaría habilitar la recarga, debe manejar los eventos. Esto se puede hacer importando el enrutador, vinculando los eventos e invocando un método de inicialización que restablece el estado de su componente y vuelve a buscar datos si es necesario.
export class InviteComponent implements OnInit, OnDestroy {
navigationSubscription;
constructor(
// … your declarations here
private router: Router,
) {
// subscribe to the router events. Store the subscription so we can
// unsubscribe later.
this.navigationSubscription = 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.
}
ngOnDestroy() {
if (this.navigationSubscription) {
this.navigationSubscription.unsubscribe();
}
}
}
Con todos estos pasos en su lugar, debe habilitar la recarga de ruta.
Esto funcionó para mí:
let url = `departments/${this.id}/employees`;
this.router.navigated = false;
this.router.navigateByUrl(url);
Esto me funciona como un encanto
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
// or
return true;
};
Estoy usando
setTimeout
y
navigationByUrl
para resolver este problema ... Y está funcionando bien para mí.
Se redirige a otra URL y, en su lugar, vuelve a aparecer en la URL actual ...
setTimeout(() => {
this.router.navigateByUrl(''/dashboard'', {skipLocationChange: false}).then(() =>
this.router.navigate([route]));
}, 500)
Existen diferentes enfoques para actualizar la ruta actual
Cambiar el comportamiento del enrutador (desde Angular 5.1) Configure los enrutadores enSameUrlNavigation para ''recargar''. Esto emitirá los eventos del enrutador en la misma navegación URL.
- Luego puede manejarlos suscribiéndose a una ruta
- Puede usarlo con la combinación de runGuardsAndResolvers para volver a ejecutar resolvers
Deje el enrutador intacto
- Pase un queryParam de actualización con la marca de tiempo actual en la URL y suscríbase a queryParams en su componente enrutado.
- Utilice el evento de activación de la salida del enrutador para obtener el componente enrutado.
He escrito una explicación más detallada en https://medium.com/@kevinkreuzer/refresh-current-route-in-angular-512a19d58f6e
Espero que esto ayude.
Hasta donde yo sé, esto no se puede hacer con el enrutador en Angular 2. Pero podría hacer lo siguiente:
window.location.href = window.location.href
Para recargar la vista.
Muy frustrante que Angular todavía no parece incluir una buena solución para esto. He planteado un problema de github aquí: https://github.com/angular/angular/issues/31843
Mientras tanto, esta es mi solución.
Se basa en algunas de las otras soluciones sugeridas anteriormente, pero creo que es un poco más robusto.
Implica envolver el servicio de enrutador en un "
ReloadRouter
", que se encarga de la funcionalidad de recarga y también agrega un
RELOAD_PLACEHOLDER
a la configuración del enrutador central.
Esto se utiliza para la navegación intermedia y evita la activación de otras rutas (o guardias).
Nota:
Solo use el
ReloadRouter
en esos casos cuando
desee
la funcionalidad de recarga.
Utilice el
Router
normal de lo contrario.
import { Injectable } from ''@angular/core'';
import { NavigationExtras, Router } from ''@angular/router'';
@Injectable({
providedIn: ''root''
})
export class ReloadRouter {
constructor(public readonly router: Router) {
// Note that this is the root-level Router instance, because ReloadRouter is provided in ''root''
router.config.unshift({ path: ''RELOAD_PLACEHOLDER'' });
}
public navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> {
return this.router
.navigateByUrl(''/RELOAD_PLACEHOLDER'', {skipLocationChange: true})
.then(() => this.router.navigate(commands, extras));
}
}
Para mí trabaja hardcoding con
this.router.navigateByUrl(''/'', {skipLocationChange: true}).then(()=>
this.router.navigate([<route>]));
Poco complicado: usa el mismo camino con algunos params ficticios. Por ejemplo-
refresh(){
this.router.navigate(["/same/route/path?refresh=1"]);
}
Prueba esto
window.open (''tablero'', ''_self'');
es un método antiguo pero funciona en todas las versiones angulares, donde redirige en la ruta y actualiza la página.
Se resolvió un escenario similar mediante el uso de un componente ficticio y una ruta para la
reload
, que en realidad hace una
redirect
.
Esto definitivamente no cubre todos los escenarios de usuario, sino que simplemente funcionó para mi escenario.
import { Component, OnInit } from ''@angular/core'';
import { Router, ActivatedRoute } from ''@angular/router'';
import { Http } from ''@angular/http'';
@Component({
selector: ''reload'',
template: `
<h1>Reloading...</h1>
`,
})
export class ReloadComponent implements OnInit{
constructor(private router: Router, private route: ActivatedRoute) {
}
ngOnInit() {
const url = this.route.snapshot.pathFromRoot.pop().url.map(u => u.path).join(''/'');
this.router.navigateByUrl(url);
}
}
El enrutamiento está conectado para capturar todas las URL usando un comodín:
import { RouterModule } from ''@angular/router'';
import { NgModule } from ''@angular/core'';
import { LoginViewComponent } from ''./views/login/login.component'';
import { HomeViewComponent } from ''./views/home/home.component'';
import { ReloadComponent } from ''./views/reload/reload.component'';
@NgModule({
declarations: [
LoginViewComponent, HomeViewComponent, ReloadComponent
],
imports: [
RouterModule.forRoot([
{ path: ''login'', component: LoginViewComponent },
{ path: ''home'', component: HomeViewComponent },
{
path: ''reload'',
children: [{
path: ''**'',
component: ReloadComponent
}]
},
{ path: ''**'', redirectTo: ''login''}
])
],
exports: [
RouterModule,
],
providers: [],
})
export class AppRoutingModule {}
Para usar esto, solo necesitamos agregar recargar a la url donde queremos ir:
this.router.navigateByUrl(''reload/some/route/again/fresh'', {skipLocationChange: true})
Si está cambiando la ruta a través de Router Link, siga esto:
constructor(public routerNavigate: Router){
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
};
this.router.events.subscribe((evt) => {
if (evt instanceof NavigationEnd) {
this.router.navigated = false;
}
})
}
Si su navegador () no cambia la URL que ya se muestra en la barra de direcciones de su navegador, el enrutador no tiene nada que hacer. No es el trabajo del enrutador actualizar los datos. Si desea actualizar los datos, cree un servicio inyectado en el componente e invoque la función de carga en el servicio. Si se recuperan los nuevos datos, actualizará la vista mediante enlaces.
Suponga que la ruta del componente que desea actualizar es
view
, luego use esto:
this.router.routeReuseStrategy.shouldReuseRoute = function (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) {
if (future.url.toString() === ''view'' && curr.url.toString() === future.url.toString()) {
return false;
}
return (future.routeConfig === curr.routeConfig);
};
puede agregar un
debugger
dentro del método para saber cuál será la ruta exacta después de navegar a
"departments/:id/employees"
.
Un poco duro pero
this.router.onSameUrlNavigation = ''reload'';
this.router.navigateByUrl(this.router.url).then(() => {
this.router.onSameUrlNavigation = ''ignore'';
});
Una solución es pasar un parámetro ficticio (es decir, el tiempo en segundos), de esta manera el enlace siempre se recarga:
this.router.navigate(["/url", {myRealData: RealData, dummyData: (new Date).getTime()}])
implementar OnInit y llamar a ngOnInit () en el método para route.navigate ()
Ver un ejemplo:
export class Component implements OnInit {
constructor() { }
refresh() {
this.router.navigate([''same-route-here'']);
this.ngOnInit(); }
ngOnInit () {
}
solo use el método de recarga de javascript nativo:
reloadPage() {
window.location.reload();
}
suscribirse a los cambios de parámetros de ruta
// parent param listener ie: "/:id"
this.route.params.subscribe(params => {
// do something on parent param change
let parent_id = params[''id'']; // set slug
});
// child param listener ie: "/:id/:id"
this.route.firstChild.params.subscribe(params => {
// do something on child param change
let child_id = params[''id''];
});
tech-blog.maddyzone.com/angularjs/javascript/… enlace muy útil para recargar ruta actual en angualr 2 o 4
en este definir dos técnicas para hacer esto
- con parámetros de consulta ficticios
- con ruta ficticia
para más información ver enlace de arriba
Hack de recarga angular de 2-4 rutas
Para mí, usar este método dentro de un componente raíz (componente, que está presente en cualquier ruta) funciona:
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]);
});
}