繁体   English   中英

子组件未在父路由更改时更新

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM