¿Cómo obtengo los RouteParams de un componente principal?
App.ts
:
@Component({
...
})
@RouteConfig([
{path: '/', component: HomeComponent, as: 'Home'},
{path: '/:username/...', component: ParentComponent, as: 'Parent'}
])
export class HomeComponent {
...
}
Y luego, en el ParentComponent
, puedo obtener fácilmente mi parámetro de nombre de usuario y configurar las rutas secundarias.
Parent.ts
:
@Component({
...
})
@RouteConfig([
{ path: '/child-1', component: ChildOneComponent, as: 'ChildOne' },
{ path: '/child-2', component: ChildTwoComponent, as: 'ChildTwo' }
])
export class ParentComponent {
public username: string;
constructor(
public params: RouteParams
) {
this.username = params.get('username');
}
...
}
Pero entonces, ¿cómo puedo obtener este mismo parámetro de 'nombre de usuario' en esos componentes secundarios? Hacer el mismo truco anterior, no lo hace. ¿Porque esos parámetros están definidos en ProfileComponent o algo así?
@Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(
public params: RouteParams
) {
this.username = params.get('username');
// returns null
}
...
}
angular
angular2-routing
Aico Klein Ovink
fuente
fuente
<child-one-component [username]="username"> ...
<routerlink [username]="username">...
? ¿Y es ese el camino a seguir entonces @MarkRajcok?<a [router-link]="[ './....', {username: username} ]
funcionará. Lo siento, no tengo ni idea de si funcionará o no. (No he jugado mucho con las rutas todavía)<router-outlet></router-outlet>
, ¿debo poner una entrada en eso? Porque las rutas secundarias se renderizarán allí ..Respuestas:
ACTUALIZAR:
Ahora que Angular2 final se lanzó oficialmente, la forma correcta de hacerlo es la siguiente:
ORIGINAL:
Así es como lo hice usando el paquete "@ angular / router": "3.0.0-alpha.6":
En este ejemplo, la ruta tiene el siguiente formato: / parent /: id / child /: childid
fuente
parent
1 vez. Consulte stackoverflow.com/a/48511516/4185989 Sin embargo, aún vale la pena considerar el patrónsubscribe
/unsubscribe
de esta respuesta.this.activatedRoute.parent.snapshot.params.someParam
No debe intentar usar
RouteParams
en suChildOneComponent
.¡Úsalo en su
RouteRegistry
lugar!ACTUALIZACIÓN: A partir de esta solicitud de extracción (angular beta.9): https://github.com/angular/angular/pull/7163
Ahora puede acceder a la instrucción actual sin
recognize(location.path(), [])
.Ejemplo:
Aún no lo he probado
Más detalles aquí:
https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta9-2016-03-09 https://angular.io/docs/ts/latest/api/router/Router-class .html
ACTUALIZACIÓN 2: Un pequeño cambio a partir de angular 2.0.0.beta15:
Ahora
currentInstruction
ya no es una función. Además, debes cargar elroot
enrutador. (gracias a @ Lxrd-AJ por informar)fuente
_router.root.currentInstruction.component.params['id']
. Énfasis en la raíz, ya que ahora obtiene la instrucción actual del enrutador raíz y no_router
. PD: estoy usandoangular2.0.0-beta.15
Como lo mencionó Günter Zöchbauer, utilicé el comentario en https://github.com/angular/angular/issues/6204#issuecomment-173273143 para abordar mi problema. Usé la
Injector
clase deangular2/core
para recuperar los parámetros de ruta del padre. Resulta que angular 2 no maneja rutas profundamente anidadas. Tal vez agreguen eso en el futuro.fuente
Encontré una solución fea pero funcional, solicitando el inyector principal (precisamente el segundo ancestro) y obteniendo el
RouteParams
de aquí.Algo como
fuente
RC5 + @ angular / enrutador ":" 3.0.0-rc.1 SOLUCIÓN: Parece que
this.router.routerState.queryParams
ha quedado en desuso. Puede obtener los parámetros de la ruta principal de esta manera:fuente
Puede tomar el componente de la ruta principal dentro del componente secundario del inyector y luego obtener cualquiera del componente secundario. En tu caso como este
fuente
Pasar la instancia del inyector al constructor en el componente hijo puede no ser bueno si desea escribir pruebas unitarias para su código.
La forma más fácil de evitar esto es tener una clase de servicio en el componente principal, en la que guarda los parámetros necesarios.
Luego, simplemente inyecta el mismo servicio a los componentes secundarios y accede a los parámetros.
Tenga en cuenta que debe limitar dicho servicio a su componente principal y sus componentes secundarios utilizando "proveedores" en el decorador de componentes principales.
Recomiendo este artículo sobre DI y alcances en Angular 2: http://blog.ilsttram.io/angular/2015/08/20/host-and-visibility-in-angular-2-dependency-injection.html
fuente
En RC6, enrutador 3.0.0-rc.2 (probablemente también funcione en RC5), puede tomar los parámetros de ruta de la URL como una instantánea en caso de que los parámetros no cambien, sin observables con este trazador de líneas:
this.route.snapshot.parent.params['username'];
No olvide inyectar ActivatedRoute de la siguiente manera:
constructor(private route: ActivatedRoute) {};
fuente
Con RxJS
Observable.combineLatest
, podemos obtener algo parecido al manejo de parámetros idiomáticos:import 'rxjs/add/operator/combineLatest'; import {Component} from '@angular/core'; import {ActivatedRoute, Params} from '@angular/router'; import {Observable} from 'rxjs/Observable'; @Component({ /* ... */ }) export class SomeChildComponent { email: string; id: string; constructor(private route: ActivatedRoute) {} ngOnInit() { Observable.combineLatest(this.route.params, this.route.parent.params) .forEach((params: Params[]) => { this.id = params[0]['id']; this.email = params[1]['email']; }); } }
fuente
Terminé escribiendo este tipo de truco para Angular 2 rc.1
import { Router } from '@angular/router-deprecated'; import * as _ from 'lodash'; interface ParameterObject { [key: string]: any[]; }; /** * Traverse route.parent links until root router and check each level * currentInstruction and group parameters to single object. * * e.g. * { * id: [314, 593], * otherParam: [9] * } */ export default function mergeRouteParams(router: Router): ParameterObject { let mergedParameters: ParameterObject = {}; while (router) { let currentInstruction = router.currentInstruction; if (currentInstruction) { let currentParams = currentInstruction.component.params; _.each(currentParams, (value, key) => { let valuesForKey = mergedParameters[key] || []; valuesForKey.unshift(value); mergedParameters[key] = valuesForKey; }); } router = router.parent; } return mergedParameters; }
Ahora, a la vista, recopilo los parámetros a la vista en lugar de leerlos
RouteParams
, solo los obtengo a través del enrutador:@Component({ ... }) export class ChildishComponent { constructor(router: Router) { let allParams = mergeRouteParams(router); let parentRouteId = allParams['id'][0]; let childRouteId = allParams['id'][1]; let otherRandomParam = allParams.otherRandomParam[0]; } ... }
fuente
MergedRouteParams
clase que implementa elget
método de laRouteParams
clase estándar (el segundo parámetro es el índice, el valor predeterminado es cero).En FINAL, con poca ayuda de RXJS , puede combinar ambos mapas (del niño y del padre):
Otras preguntas que uno podría tener:
fuente
Puede hacerlo en la instantánea con lo siguiente, pero si cambia, su
id
propiedad no se actualizará.Este ejemplo también muestra cómo puede suscribirse a todos los cambios de parámetros de antepasados y buscar el que le interesa fusionando todos los parámetros observables. Sin embargo, tenga cuidado con este método porque podría haber varios ancestros que tengan el mismo nombre / clave de parámetro.
import { Component } from '@angular/core'; import { ActivatedRoute, Params, ActivatedRouteSnapshot } from '@angular/router'; import { Observable } from 'rxjs/Observable'; import { Subscription } from 'rxjs/Subscription'; import 'rxjs/add/observable/merge'; // This traverses the route, following ancestors, looking for the parameter. function getParam(route: ActivatedRouteSnapshot, key: string): any { if (route != null) { let param = route.params[key]; if (param === undefined) { return getParam(route.parent, key); } else { return param; } } else { return undefined; } } @Component({ /* ... */ }) export class SomeChildComponent { id: string; private _parameterSubscription: Subscription; constructor(private route: ActivatedRoute) { } ngOnInit() { // There is no need to do this if you subscribe to parameter changes like below. this.id = getParam(this.route.snapshot, 'id'); let paramObservables: Observable<Params>[] = this.route.pathFromRoot.map(route => route.params); this._parametersSubscription = Observable.merge(...paramObservables).subscribe((params: Params) => { if ('id' in params) { // If there are ancestor routes that have used // the same parameter name, they will conflict! this.id = params['id']; } }); } ngOnDestroy() { this._parameterSubscription.unsubscribe(); } }
fuente
Obtener RouteParams del componente principal en Angular 8 -
Tengo una ruta http: // localhost: 4200 / partner / student-profile / 1234 / info
Ruta principal - perfil del alumno
Param - 1234 (estudiante_id)
Ruta del niño - info
Accediendo al parámetro en la ruta secundaria (info) -
Importar
Constructor
Acceder a los parámetros de la ruta principal
Ahora, nuestra variable studentId tiene el valor param.
fuente