Ruta de recarga Angular 2 en cambio de param


Actualmente estoy escribiendo mi primera aplicación Angular 2. Tengo un OverviewComponent que tiene la siguiente plantilla simple:

<div class="row">
  <div class="col-lg-8">
    <router-outlet></router-outlet>
  </div>
  <div class="col-lg-4">
    <app-list></app-list>
  </div>
</div>

Al acceder a la url / mi enrutador me redirige a /overview, que luego carga un mapa dentro de la toma de corriente del enrutador. El <app-list> tiene una lista de elementos clicables que desencadena un <app-detail> que se mostrará en lugar del componente de la aplicación. Por lo tanto paso el id del archivo json de referencia en la url así: /details/:id (en mis rutas).

Todas las obras anteriores totalmente bien. Si ahora hago clic en uno de los elementos de la lista, se muestran los detalles, PERO cuando selecciono otro elemento de la lista, la vista no cambia a los nuevos detalles. La URL cambia, pero el contenido no se vuelve a cargar. ¿Cómo puedo lograr una reinicialización del DetailComponent?

Author: hGen, 2016-08-16

8 answers

Según la primera versión final, esto se resuelve.

Simplemente preste mucha atención para restablecer correctamente el estado del componente cuando el parámetro cambie

this.route.params.subscribe(params => {
    this.param = params['yourParam'];
    this.initialiseState(); // reset and set based on new parameter this time
});
 26
Author: gpanagopoulos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-08 20:27:00

Puede cambiar el RouteReuseStrategy directamente en el nivel de componente:

constructor(private router: Router) {

      // force route reload whenever params change;
      this.router.routeReuseStrategy.shouldReuseRoute = () => false;

}

Del mismo modo, la estrategia de reutilización se puede cambiar globalmente.

Esto no necesariamente aborda su problema directamente, pero ver cómo esta pregunta es el primer resultado de búsqueda para "url de recarga angular 2 si cambian los parámetros de consulta" podría evitar que la siguiente persona investigue los problemas de github.

 22
Author: Nik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-14 14:43:21

No se si hay una respuesta al problema similar a la que voy a proponer aquí, así que lo haré de todos modos:

Me las arreglé para lograr una recarga 'falsa' de la siguiente manera.

Lo que básicamente hice fue crear un Componente que me redirige al componente 'real' que quiero usar:

@Component({
  selector: 'camps-fake',
  template: ''
})
export class FakeComponent implements OnInit {

  constructor(private _router:Router,
              private _route:ActivatedRoute)
  { }

  ngOnInit() {
    let id:number = -1;
    this._route.params.forEach((params:Params) => {
      id = +params['id'];
    });

    let link:any[] = ['/details', id];
    this._router.navigate(link);
  }

}

Así que al seleccionar un elemento de lista, el enrutador navegará a /fake/:id que simplemente extrae el id de la URL y navega al componente 'real'.

Lo sé puede haber una manera más fácil, o más elegante, pero creo que esta solución funciona bastante bien ya que la falsificación realmente no atrae la atención. Solo el 'parpadeo' cuando la página se vuelve a cargar es un aspecto negativo, pero en lo que respecta a mi conocimiento de css puede haber alguna transición para cubrir eso.

 7
Author: hGen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-07 12:52:51

Otra alternativa que debe agregarse aquí es proporcionar un RouteReuseStrategy a su módulo.

providers: [
  {
    provide: RouteReuseStrategy,
    useClass: AARouteReuseStrategy
  }
]

El comportamiento predeterminado del enrutador es reutilizar la ruta si la configuración es la misma (que es el caso cuando solo se cambia el parámetro :id en esta pregunta). Al cambiar la estrategia para no reutilizar la ruta, el componente se recargará y no tendrá que suscribirse a los cambios de ruta en el componente.

Una implementación de la estrategia Routereusestry podría ser así:

export class AARouteReuseStrategy extends RouteReuseStrategy {
  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  store(route: ActivatedRouteSnapshot, handle: {}): void {

  }
  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  retrieve(route: ActivatedRouteSnapshot): {} {
     return null;
 }
 shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
   return false; // default is true if configuration of current and future route are the same
 }
}

He escrito algo al respecto aquí también:

Https://pjsjava.blogspot.no/2018/01/angular-components-not-reloading-on.html

 7
Author: Peter Salomonsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-11 10:10:52

Es posible detectar cualquier cambio en los parámetros recibidos, en mi caso cargo la información usando un Resolve por lo que no necesito el parámetro (solo detectar si cambia). Esta es mi solución final:

public product: Product;
private parametersObservable: any;

constructor(private route: ActivatedRoute) {
}

ngOnInit() {
  this.parametersObservable = this.route.params.subscribe(params => {
    //"product" is obtained from 'ProductResolver'
    this.product = this.route.snapshot.data['product'];
  });
}

//Don't forget to unsubscribe from the Observable
ngOnDestroy() {
  if(this.parametersObservable != null) {
    this.parametersObservable.unsubscribe();
  }
}
 3
Author: Alexis Gamarra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-22 09:47:50

Lo resolví usando event, si el componente hijo envía un nuevo enlace y emite un evento, entonces el padre puede encontrar el cambio y llamar a alguna función de recarga, que recargará los datos necesarios. Otra opción es suscribirse a los parámetros de ruta , y se encuentra cuando cambia Pero creo que los chicos de angular2 deberían pensar en agregar parámetros al router.función de navegación, que puede forzar la recarga. (forceReload = true)

 2
Author: user3728728,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:37

Esto actualmente no está soportado directamente. Ver también https://github.com/angular/angular/issues/9811

Lo que puedes hacer es algo como

<div *ngIf="doShow" class="row">
  <div class="col-lg-8">
    <router-outlet></router-outlet>
  </div>
  <div class="col-lg-4">
    <app-list></app-list>
  </div>
</div>
doShow:boolean: true;

constructor(private _activatedRoute: ActivatedRoute, private _router:Router, private cdRef:ChangeDetectorRef) {
  _router.routerState.queryParams.subscribe(
    data => {
      console.log('queryParams', data['st']); 
      this.doShow = false;
      this.cdRef.detectChanges();
      this.doShow = true;
  });
}

(no probado)

 1
Author: Günter Zöchbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-16 10:00:48
this.route.paramMap.subscribe(params => {
  //fetch your new parameters here, on which you are switching the routes and call ngOnInit()
  this.ngOnInit();
 });

Solo necesitas llamar a ngOnInit() desde dentro del paramMap y inicializará toda la página con los datos recién cargados.

 0
Author: cyperpunk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-20 07:15:04