2016-11-11 63 views
0

我一直在试图学习angular 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我克ot到goals/1/experiments/1/notes该网址是正确的,我看到了正确的实验1的注释

如果我再点击实验2在实验列表goals/1/experiments/2/notes的URL是正确的实验细节是正确的,但在纸币仍在实验1个的Notes

如果我再刷新浏览器,实验2个负载和笔记现在实验2个的Notes这是正确的。

这是我如何得到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); 

我敢肯定,这是一个明显的错误,我正在做,但对于我的生活我无法看到我的错在哪里。

回答

1

这是因为ngOnInit()方法是在创建组件期间仅调用。当你点击实验2时,你不会创建一个新的实验组件。你只是使用旧的。

Url正在改变,因为您仍然订阅了路由参数。但您的服务电话不在Observable中。因此,只需将服务调用放入您的obserable中,然后每次更改路由参数时,都会加载新数据。

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

的API已经改变了不少最新版本角5.2.5 作为埃姆雷说,问题是,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(

相关问题