我有一个仪表板应用程序,它包含一个树视图组件(列出各种内容节点)和一个仪表板编辑组件,它根据树的哪个分支选择呈现一些可编辑的内容。
e.g。树是这样的:
- Football
- - Premier League
- - - Arsenal
- - - Chelsea
- - - ...etc
- - Championship
- - - Derby
- - - ...etc
点击树中的“Arsenal”,它会在页面上的可编辑面板中为该团队呈现一些内容。
呈现子组件的组件如下:
@Component({
selector: 'my-dashboard',
template: `
<div class="tree-panel-container">
<div class="tree-panel-content">
<content-tree [startNodeId]="startNodeIdContent"></content-tree>
</div>
</div>
<router-outlet></router-outlet>
`,
directives: [
ContentTreeComponent,
ContentDashboardComponent,
RouterOutlet
],
providers: [
HTTP_PROVIDERS
]
})
可编辑内容以router-outlet
呈现,以便每个可编辑的内容都有自己独特的网址,例如example.com/content/edit/123
其中123
是阿森纳内容的ID,例如。
一切正常。
但是,我想要做的是能够访问id
组件中的content-tree
路由参数。目前,我非常确定我在该组件中的代码应该工作:
import {Component, Input, OnInit} from '@angular/core';
import {Router, RouteParams} from '@angular/router-deprecated';
import {ContentNode} from './content-node';
import {ContentService} from '../services/content.service';
@Component({
selector: 'content-tree',
directives: [ContentTreeComponent],
template: `
<ol class="tree">
<li *ngFor="let contentNode of contentNodes" class="tree__branch" [ngClass]="{'tree__branch--has-children': contentNode.HasChildren}">
<a *ngIf="contentNode.HasChildren" (click)="contentNode.toggle=!contentNode.toggle" class="tree__branch__toggle">
{{ !!contentNode.toggle ? '-' : '+' }}
</a>
<a class="tree__branch__link" (click)="onSelect(contentNode)">{{ contentNode.Name }}</a>
<content-tree *ngIf="contentNode.toggle" [startNodeId]="contentNode.Id"></content-tree>
</li>
</ol>
<div class="error" *ngIf="errorMessage">{{errorMessage}}</div>
`
})
export class ContentTreeComponent implements OnInit {
constructor(
private _contentService: ContentService,
private _router: Router,
private _routeParams: RouteParams
) { }
errorMessage: string;
@Input('startNodeId')
private _startNodeId: number;
contentNodes: ContentNode[];
ngOnInit() {
let nodeId = +this._routeParams.get('id');
console.log('nodeId = ' + nodeId);
this.getContentNodes();
}
onSelect(contentNode: ContentNode) {
this._router.navigate( ['ContentEdit', { id: contentNode.Id }] );
}
getContentNodes() {
this._contentService.getContentNodes(this._startNodeId)
.subscribe(
contentNodes => this.contentNodes = contentNodes,
error => this.errorMessage = <any>error
);
}
}
但nodeId
方法中的ngOnInit
变量始终返回为0
。
问题: 是否只能访问由路由器出口提供的组件中的路由参数?如果是这样,那么处理这个的最好方法是创建第二个(命名,因为现在会有2个)路由器插座?如果没有,那么我做错了什么?
非常感谢。
修改
一个工作(并且非常丑陋;))现在已生成Plnkr以显示应用程序的基础知识:http://plnkr.co/edit/W3PVk3Ss5Wq59IbnLjaK?p=preview。请参阅有关应该发生的事情的评论......
答案 0 :(得分:12)
我找到了一种很好的方法,可以从应用程序内的任何位置获取显示路径中的所有params,queryParmas,segment和fragment。只需将此代码添加到您需要的任何组件,或创建可在整个应用程序中注入的服务。
import { Router, NavigationEnd } from "@angular/router";
import { Component, OnInit } from '@angular/core';
...
export class MyComponentOrService implements OnInit {
constructor(private router: Router) {}
ngOnInit() {
/* this subscription will fire always when the url changes */
this.router.events.subscribe(val=> {
/* the router will fire multiple events */
/* we only want to react if it's the final active route */
if (val instanceof NavigationEnd) {
/* the variable curUrlTree holds all params, queryParams, segments and fragments from the current (active) route */
let curUrlTree = this.router.parseUrl(this.router.url);
console.info(curUrlTree);
}
});
}
...
答案 1 :(得分:4)
是否只能访问路由器插座呈现的组件中的路由参数?
是的,<router-outlet></router-outlet>
告诉 Angular2 将包含的组件视为&#34;路由&#34;零件。因此,您无法将RouteParams
实例注入到类中,因为它没有通过路由指令实例化。
如果没有,那么我做错了什么?
我不会说你做错了什么,你只是误解了它的设计方式。我也有这种最初的误解。我发现this Angular2 文章是理解如何传递数据以及如何在父组件和子组件之间进行通信的重要来源。
<小时/> 在您的具体情况下,我建议您从RouteParams
的{{1}}删除constructor
,因为只有从&#34;路由&#34;组件。
ContentTreeComponent
然后,为了获得export class ContentTreeComponent implements OnInit {
constructor(
private _contentService: ContentService,
private _router: Router
) { }
// Omitted for brevity...
}
,您可能需要分享更多顶级代码,以便我可以看到它的来源......
答案 2 :(得分:3)
在新路由器(&gt; = RC.0&lt; = RC.2 )中,这将是
import 'rxjs/add/operator/first';
...
constructor(private router:Router, private routeSerializer:RouterUrlSerializer, private location:Location) {
router.changes.first().subscribe(() => {
let urlTree = this.routeSerializer.parse(location.path());
console.log('id', urlTree.children(urlTree.children(urlTree.root)[0])[0].segment);
});
}
答案 3 :(得分:0)
由于此帖中找到的解决方案无法解决我的问题,我刚刚添加了另一个解决方案,该解决方案目前可以修复或帮助您在其他帖子中处理此类问题问题类似:Angular 2: How do I get params of a route from outside of a router-outlet
答案 4 :(得分:0)
此解决方案对我有用:complete example。
constructor(
private readonly router: Router,
private readonly rootRoute: ActivatedRoute,
){
router.events.pipe(
filter(e => e instanceof NavigationEnd),
map(e => this.getParams(this.rootRoute))
).subscribe(params => {
//
});
}
private getParams(route: ActivatedRoute): Params {
// route param names (eg /a/:personId) must be ditinct within
// a route otherwise they'll be overwritten
let params = route.snapshot.params
params = { ...route.snapshot.queryParams, ...params}
if(route.children){
for(let r of route.children){
params = {...this.getParams(r), ...params};
}
}
return params;
}
贷记Toxicable。