[英]Child component not updating on parent route change
我一直在尝试按照本教程[Build an application with Angular 2 and Firebase][1]
来学习 angular 2,并尝试对其进行扩展。 但是我在尝试嵌套多条路线时遇到了障碍。
应用结构:
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
的URL是正确的,我看到正确的实验1的注意事项。
如果我再在实验列表点击实验2 goals/1/experiments/2/notes
的URL是正确的实验细节是正确的,但在纸币仍在实验1和的注意事项。
如果我然后刷新浏览器,将加载实验 2 ,注释现在是正确的实验 2 的注释。
这就是我如何获得用于检索笔记的experimentId
ID
实验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);
我确信这是我犯的一个明显的错误,但对于我的生活,我看不出我哪里出错了。
这是因为 ngOnInit() 方法在创建组件期间只调用一次。 当您单击实验 2 时,您不会创建新的实验组件。 你只用旧的。
Url 正在更改,因为您仍然订阅了路由参数。 但是您的 Service 调用不在 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);
});
API 在最新版本的angular 5.2.5 中发生了很大变化 正如 Emre 所说,问题是 ngOnInit 在第一次创建子组件时只调用一次,创建后需要通知组件 url 的更改,以便它可以再次获取参数,这可以通过在 Router 对象上添加一个侦听器然后使用路由对象来获取所需的部分来完成。 下面是一些基于英雄之旅示例应用程序的示例代码:
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()
activateRoute 具有父属性。 只需要订阅子组件中的参数,如下所示:
this.route.parent.params.subscribe((params: Params) => {
// some stuff
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.