[英]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.