我一直在尝试学习角度2以及本教程[Build an application with Angular 2 and Firebase][1]
,并尝试对其进行扩展。但是当我试图嵌套多条路线时,我遇到了麻烦。
应用结构:
Goals – (has router-outlet)
> Single Goal with Experiments list – (has router-outlet)
> Single Experiment – (has router-outlet)
> Experiment Notes
路由器设置:
export const routerConfig : Route[] = [
{
path: 'goals',
children: [
{
path: ':id', component: SingleGoalComponent,
children: [
{
path: 'experiments',
children: [
{ path: ':id', component: ExperimentDetailsComponent,
children: [
{ path: '', redirectTo: 'notes', pathMatch: 'full' },
{ path: 'notes', component: ExperimentNotesComponent }
]
},
{ path: 'new', component: NewExperimentComponent },
{ path: '' }
]
},
{ path: '', redirectTo: 'experiments', pathMatch: 'full' }
]
},
{ path: '', component: GoalsComponent }
]
},
{ path: 'notes', component: NotesComponent },
{ path: '', redirectTo: 'goals', pathMatch: 'full' },
{ path: '**', redirectTo: 'goals', pathMatch: 'full' }
];
问题
如果我点击实验列表中的实验1 ,我得到了goals/1/experiments/1/notes
,网址是正确的,我看到了正确的实验1的注释
如果我然后点击实验列表goals/1/experiments/2/notes
中的实验2 ,网址是正确的,实验详细信息是正确的,但笔记仍然是实验1&#39}
如果我然后刷新浏览器,实验2 加载并且笔记现在是实验2的注释,这是正确的。
这就是我获取experimentId
来检索笔记的方法
实验-notes.component.ts
experimentId: string;
goalId: string;
constructor(
private router: Router,
private route: ActivatedRoute,
private experimentsService: ExperimentsService,
private _location: Location) { }
ngOnInit() {
Observable.combineLatest(this.route.parent.params, this.route.parent.parent.params)
.forEach((params: Params[]) => {
this.experimentId = params[0]['id'];
this.goalId = params[1]['id'];
});
console.log('Experiment ID: ' + this.experimentId + '| Goal Id: ' + this.goalId);
this.notes$ = this.experimentsService.findAllNotesForExperiment(this.experimentId);
我确定这是我犯的一个明显的错误,但对于我的生活,我无法看到我在哪里出错。
答案 0 :(得分:2)
这是因为在创建组件期间,ngOnInit()方法仅调用一次。当您单击实验2时,您不会创建新的实验组件。你只需使用旧的。
网址正在发生变化,因为您仍然订阅了路线参数。但您的服务电话不在Observable中。所以只需将服务调用放入您的服务中,然后每次更改路由参数时,它都会加载新数据。
ngOnInit() {
Observable.combineLatest(this.route.parent.params, this.route.parent.parent.params)
.forEach((params: Params[]) => {
this.experimentId = params[0]['id'];
this.goalId = params[1]['id'];
console.log('Experiment ID: ' + this.experimentId + '| Goal Id: ' + this.goalId);
this.notes$ = this.experimentsService.findAllNotesForExperiment(this.experimentId);
});
答案 1 :(得分:2)
API在最新版本 angular 5.2.5 中发生了很大变化 正如Emre所说,问题是在首次创建子组件时只调用一次ngOnInit,创建后需要通知组件更改url以便它可以再次获取参数,这可以通过添加一个监听器来完成在Router对象上,然后使用route对象获取所需的部件。以下是基于英雄示例应用程序之旅的示例代码:
import {Component, Input, OnInit} from '@angular/core';
import {Hero} from '../hero';
import {HeroService} from "../hero.service";
import {ActivatedRoute, Router} from "@angular/router"; //Import Router and ActivatedRoute classes
import {Location} from '@angular/common';
import {MessageService} from "../message.service";
@Component({
selector: 'app-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {
@Input() hero: Hero;
constructor(private route: ActivatedRoute,
private heroService: HeroService,
private messageService: MessageService,
private location: Location,
private router: Router) {
}
ngOnInit(): void {
this.router.events.subscribe((val) => {//Use Router class to subscribe to events
const id = +this.route.snapshot.paramMap.get('id');//When a route event occurs use the active route to update the parameter needed
this.getHero(id);//Do what you would have initially done with the url value
});
}
getHero(id): void {
this.messageService.add(`HeroDetailComponent: fetching hero: ${id}`);
this.heroService.getHero(id)
.subscribe(hero => this.hero = hero);
}
goBack(): void {
this.location.back();
}
}
最相关的部分位于 ngOnInit()
答案 2 :(得分:0)
activatedRoute具有父属性。只需在子组件中订阅参数,如下所示:
this.route.parent.params.subscribe((params: Params) => {
// some stuff
});