如何从父组件获取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');
}
...
}
但是,如何在这些子组件中获得相同的'username'参数?做与上面相同的技巧,不会这样做。因为这些参数是在ProfileComponent中定义的还是什么?
@Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(
public params: RouteParams
) {
this.username = params.get('username');
// returns null
}
...
}
答案 0 :(得分:55)
<强>更新强>
现在Angular2 final正式发布,正确的方法如下:
export class ChildComponent {
private sub: any;
private parentRouteId: number;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.sub = this.route.parent.params.subscribe(params => {
this.parentRouteId = +params["id"];
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
<强> ORIGINAL:强>
以下是我使用“@ angular / router”:“3.0.0-alpha.6”包的方式:
export class ChildComponent {
private sub: any;
private parentRouteId: number;
constructor(
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
this.sub = this.router.routerState.parent(this.route).params.subscribe(params => {
this.parentRouteId = +params["id"];
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
在此示例中,路由具有以下格式:/ parent /:id / child /:childid
export const routes: RouterConfig = [
{
path: '/parent/:id',
component: ParentComponent,
children: [
{ path: '/child/:childid', component: ChildComponent }]
}
];
答案 1 :(得分:9)
您不应该尝试在RouteParams
中使用ChildOneComponent
。
改为使用RouteRegistry
!
@Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(registry: RouteRegistry, location: Location) {
route_registry.recognize(location.path(), []).then((instruction) => {
console.log(instruction.component.params['username']);
})
}
...
}
更新:从此拉取请求(角度测试版9)开始:https://github.com/angular/angular/pull/7163
您现在可以在不使用recognize(location.path(), [])
的情况下访问当前指令。
示例:
@Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(_router: Router) {
let instruction = _router.currentInstruction();
this.username = instruction.component.params['username'];
}
...
}
我还没有尝试过,
此处有更多详情:
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: 从角度2.0.0.beta15开始的小变化:
现在currentInstruction
不再是一个功能了。此外,您必须加载root
路由器。 (感谢@ Lxrd-AJ报道)
@Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(_router: Router) {
let instruction = _router.root.currentInstruction;
this.username = instruction.component.params['username'];
}
...
}
答案 2 :(得分:7)
如GünterZöchbauer所述,我使用https://github.com/angular/angular/issues/6204#issuecomment-173273143的评论来解决我的问题。我使用Injector
中的angular2/core
类来获取父级的路由选择。原来角度2不能处理深层嵌套的路线。也许他们将来会加上它。
constructor(private _issueService: IssueService,
private _injector: Injector) {}
getIssues() {
let id = this._injector.parent.parent.get(RouteParams).get('id');
this._issueService.getIssues(id).then(issues => this.issues = issues);
}
答案 3 :(得分:6)
我找到了一个丑陋但有效的解决方案,通过请求父母(正是第二个祖先)注射器,并从此处获取RouteParams
。
像
这样的东西@Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(injector: Injector) {
let params = injector.parent.parent.get(RouteParams);
this.username = params.get('username');
}
}
答案 4 :(得分:4)
RC5 + @ angular / router&#34;:&#34; 3.0.0-rc.1解决方案:似乎已弃用this.router.routerState.queryParams
。您可以通过这种方式获得父路线参数:
constructor(private activatedRoute: ActivatedRoute) {
}
this.activatedRoute.parent.params.subscribe(
(param: any) => {
let userId = param['userId'];
console.log(userId);
});
答案 5 :(得分:2)
您可以从注入器中获取子组件内部父路径的组件,然后从子组件获取任何组件。在你的情况下像这样
@Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(
public params: RouteParams
private _injector: Injector
) {
var parentComponent = this._injector.get(ParentComponent)
this.username = parentComponent.username;
//or
this.username = parentComponent.params.get('username');
}
...
}
答案 6 :(得分:2)
如果要为代码编写单元测试,将Injector实例传递给子组件中的构造函数可能不太好。
解决此问题的最简单方法是在父组件中创建一个服务类,您可以在其中保存所需的参数。
@Component({
template: `<div><router-outlet></router-outlet></div>`,
directives: [RouterOutlet],
providers: [SomeServiceClass]
})
@RouteConfig([
{path: "/", name: "IssueList", component: IssueListComponent, useAsDefault: true}
])
class IssueMountComponent {
constructor(routeParams: RouteParams, someService: SomeServiceClass) {
someService.id = routeParams.get('id');
}
}
然后,您只需向子组件注入相同的服务并访问参数。
@Component({
template: `some template here`
})
class IssueListComponent implements OnInit {
issues: Issue[];
constructor(private someService: SomeServiceClass) {}
getIssues() {
let id = this.someService.id;
// do your magic here
}
ngOnInit() {
this.getIssues();
}
}
请注意,您应该使用&#34; providers&#34;将此类服务的范围扩展到您的父组件及其子组件。在父组件装饰器中。
我推荐这篇关于Angular 2中的DI和范围的文章:http://blog.thoughtram.io/angular/2015/08/20/host-and-visibility-in-angular-2-dependency-injection.html
答案 7 :(得分:2)
在RC6,路由器3.0.0-rc.2 (也可能在RC5中工作),你可以从URL中获取路由参数作为快照,以防params不会改变,没有观察到这一个班轮:
this.route.snapshot.parent.params['username'];
不要忘记按如下方式注入ActivatedRoute:
constructor(private route: ActivatedRoute) {};
答案 8 :(得分:2)
使用RxJS&#39; 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'];
});
}
}
答案 9 :(得分:1)
我最终为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];
}
...
}
答案 10 :(得分:0)
在 FINAL 中,在 RXJS 的帮助下,您可以合并两张地图(来自儿童和家长):
(route) => Observable
.zip(route.params, route.parent.params)
.map(data => Object.assign({}, data[0], data[1]))
可能有的其他问题:
答案 11 :(得分:0)
您可以使用以下内容在快照上执行此操作,但如果更改,则不会更新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();
}
}
属性。
此示例还说明了如何通过合并所有参数observable来订阅所有祖先参数更改并查找您感兴趣的参数。但是,请小心使用此方法,因为可能有多个祖先具有相同的参数键/名称。
{{1}}
答案 12 :(得分:0)
从Angular 8的父组件获取RouteParams-
我有一条路线http://localhost:4200/partner/student-profile/1234/info
父母路线-学生资料
Param -1234(student_id)
子路线-信息
访问子路径中的参数(信息)-
导入
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
构造函数
constructor(private activatedRoute: ActivatedRoute, private router: Router) { }
访问父级路由参数
this.activatedRoute.parent.paramMap.subscribe((params: ParamMap) => this.studentId = (params.get('student_id')));
现在,我们的变量 studentId 具有参数值。