Как мне получить RouteParams из родительского компонента?
App.ts
:
@Component({
...
})
@RouteConfig([
{path: '/', component: HomeComponent, as: 'Home'},
{path: '/:username/...', component: ParentComponent, as: 'Parent'}
])
export class HomeComponent {
...
}
И затем, в ParentComponent
, я могу легко получить свой параметр имени пользователя и установить дочерние маршруты.
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');
}
...
}
Но тогда как я могу получить тот же параметр «имя пользователя» в этих дочерних компонентах? Выполнение того же трюка, что и выше, не поможет. Потому что эти параметры определены в ProfileComponent или что-то в этом роде ??
@Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(
public params: RouteParams
) {
this.username = params.get('username');
// returns null
}
...
}
angular
angular2-routing
Айко Кляйн Овинк
источник
источник
<child-one-component [username]="username"> ...
<routerlink [username]="username">...
? И разве тогда это путь, @MarkRajcok?<a [router-link]="[ './....', {username: username} ]
, сработает ли что-то подобное . Извините, я понятия не имею, сработает это или нет. (Я еще не очень много играл с маршрутизацией.)<router-outlet></router-outlet>
, стоит ли мне что-то добавить. Потому что там будут рендериться дочерние маршруты ..Ответы:
ОБНОВИТЬ:
Теперь, когда был официально выпущен финал Angular2, правильный способ сделать это:
ОРИГИНАЛ:
Вот как я это сделал с помощью пакета «@ angular / router»: «3.0.0-alpha.6»:
В этом примере маршрут имеет следующий формат: / parent /: id / child /: childid
источник
parent
1 раза. См. Stackoverflow.com/a/48511516/4185989 Тем не менее, стоит рассмотреть шаблонsubscribe
/unsubscribe
из этого ответа.this.activatedRoute.parent.snapshot.params.someParam
Вы не должны пытаться использовать
RouteParams
в своемChildOneComponent
.Используйте
RouteRegistry
вместо этого!ОБНОВЛЕНИЕ: Начиная с этого запроса на перенос (angular beta.9): https://github.com/angular/angular/pull/7163
Теперь вы можете получить доступ к текущей инструкции без
recognize(location.path(), [])
.Пример:
Я еще не пробовал
Подробности здесь:
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
ОБНОВЛЕНИЕ 2: Небольшое изменение по сравнению с angular 2.0.0.beta15:
Теперь
currentInstruction
это больше не функция. Кроме того, вам необходимо загрузитьroot
роутер. (спасибо @ Lxrd-AJ за сообщение)источник
_router.root.currentInstruction.component.params['id']
. Акцент на root, поскольку теперь вы получаете текущую инструкцию от корневого маршрутизатора, а не_router
. PS: Я используюangular2.0.0-beta.15
Как упоминал Гюнтер Цохбауэр, я использовал комментарий на https://github.com/angular/angular/issues/6204#issuecomment-173273143, чтобы решить свою проблему. Я использовал
Injector
класс fromangular2/core
для получения параметров маршрута родителя. Оказывается, angular 2 не обрабатывает глубоко вложенные маршруты. Может быть, они добавят это в будущем.источник
Я нашел уродливое, но рабочее решение, запросив родительский (а именно второй предок) инжектор и получив
RouteParams
отсюда.Что-то вроде
источник
RC5 + @ angular / router ":" 3.0.0-rc.1 РЕШЕНИЕ: Похоже, что
this.router.routerState.queryParams
это устарело. Вы можете получить параметры родительского маршрута следующим образом:источник
Вы можете взять компонент родительского маршрута внутри дочернего компонента из инжектора, а затем получить любой из дочернего компонента. В таком случае
источник
Передача экземпляра Injector в конструктор дочернего компонента может оказаться неэффективной, если вы хотите писать модульные тесты для своего кода.
Самый простой способ обойти это - иметь класс обслуживания в родительском компоненте, в котором вы сохраняете необходимые параметры.
Затем вы просто вставляете ту же услугу в дочерние компоненты и получаете доступ к параметрам.
Обратите внимание, что вы должны ограничить такую службу своим родительским компонентом и его дочерними компонентами, используя «поставщиков» в декораторе родительского компонента.
Я рекомендую эту статью о DI и областях действия в Angular 2: http://blog.oughttram.io/angular/2015/08/20/host-and-visibility-in-angular-2-dependency-injection.html
источник
В RC6 маршрутизатор 3.0.0-rc.2 (вероятно, также работает в RC5), вы можете взять параметры маршрута из URL-адреса в качестве снимка, если параметры не изменятся, без наблюдаемых с этим одним вкладышем:
this.route.snapshot.parent.params['username'];
Не забудьте ввести ActivatedRoute следующим образом:
constructor(private route: ActivatedRoute) {};
источник
С помощью RxJS
Observable.combineLatest
мы можем получить что-то близкое к идиоматической обработке параметров: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']; }); } }
источник
В итоге я написал такой хак для 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; }
Теперь в поле зрения я собираю параметры в поле зрения вместо того, чтобы читать,
RouteParams
я просто получаю их через маршрутизатор:@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]; } ... }
источник
MergedRouteParams
класса, который реализуетget
метод стандартногоRouteParams
класса (второй параметр - это индекс, по умолчанию равен нулю).В FINAL с небольшой помощью RXJS вы можете комбинировать обе карты ( дочернюю и родительскую):
Могут возникнуть и другие вопросы:
источник
Вы можете сделать это на снимке следующим образом, но если он изменится, ваше
id
свойство не будет обновлено.В этом примере также показано, как вы можете подписаться на все изменения параметров-предков и найти тот, который вас интересует, путем объединения всех наблюдаемых параметров. Однако будьте осторожны с этим методом, потому что может быть несколько предков с одним и тем же ключом / именем параметра.
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(); } }
источник
Получение RouteParams из родительского компонента в Angular 8 -
У меня есть маршрут http: // localhost: 4200 / partner / student-profile / 1234 / info
Родительский маршрут - профиль студента
Парам - 1234 (student_id)
Детский маршрут - информация
Доступ к параметру в дочернем маршруте (информация) -
импорт
Конструктор
Доступ к параметрам родительского маршрута
Теперь наша переменная studentId имеет значение параметра.
источник