簡體   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