简体   繁体   中英

Going to route/id doesn't cause template update (address bar shows correct route/id)

I'm just learining angular so sorry if it turns out to be silly question. I have a basic app where I have left-side panel (sidenav material component) and content area. In the left-side panel I have a list of machines (machine s Componenet) and when user clicks any of them, matching machine (machineComponent) should be loaded to content area. Content area contains named router-outlet ('main'), so I managed to get this to work. When the user clicks for the first time some machine in the left-side panel, it gets loaded - this is visibible both in address bar and in machine template displaying its id (taken from the route at init). The weird issue I'm having is that when the user clicks another machine, address bar apparently goes there (machine/id changes) but the template still shows the initial id. No matter how many more machines the user clicks, address bar always update but the template stays on the initial id. I've debugged it by putting breakpoint at machine constructor, and it seems it's called only once (doens't get called when user clicks other machine)..

Routing:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MachinesComponent } from './machines/machines.component';
import { MachineComponent } from './machine/machine.component';
import { LinePerformanceComponent } from './line-performance/line-performance.component';

const routes: Routes = [
  { path: 'machines', component: MachinesComponent},
  { path: 'lineperformance', component: LinePerformanceComponent, children: [
    { path: 'machine/:id', component: MachineComponent, outlet: 'main'}
  ]},
  { path: '', redirectTo: '/lineperformance', pathMatch: 'full'}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Machines template:

<mat-nav-list>
  <a *ngFor="let machine of machines" class="nav-item" mat-list-item [routerLink]="['/lineperformance', { outlets: {
      main: ['machine', machine.id]
    }}]">
    <mat-icon [ngClass]="machine.state=='PR'?'green-icon':'red-icon'">stop_circle</mat-icon>  
    {{ machine.name}}
  </a>
</mat-nav-list>

Machine component:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { Machine } from '../machine';

@Component({
  selector: 'app-machine',
  templateUrl: './machine.component.html',
  styleUrls: ['./machine.component.css']
})
export class MachineComponent implements OnInit {
  machine: Machine;
  id: number;
  name: string;
  state: string;

  constructor(
    private route: ActivatedRoute,
    private location: Location
  ) { }

  ngOnInit() {
    this.id = +this.route.snapshot.paramMap.get('id');
  }

}

Lineperformance template (sidenav and content area container): <

mat-sidenav-container>
    <mat-sidenav mode="side" [(opened)]="menuOpened">
      <app-machines></app-machines>
    </mat-sidenav>
    <mat-sidenav-content>
      <button [ngClass]="menuOpened?'menuToggle-expanded':'menuToggle-collapsed'" id="menuToggle" mat-mini-fab color="primary" (click)="menuOpened=!menuOpened">
        <mat-icon>menu</mat-icon>
      </button>
      <router-outlet name="main"></router-outlet>
    </mat-sidenav-content>
  </mat-sidenav-container>

I don't think any other file is significant for this issue, but if it is, you can find complete project here .

Sorry, can't update the question. I simplified the code. Now machine component should load to default router-outlet, which is located in mat-sidenav-content. This works for the very first time and not anymore. The second (and subsequent) item you choose from sidenav, address bar changes (correctly) but the machine template doesn't update. I debugged it and constructor in machine component is load only the first time, whereas it should load each time you click an item..

Please check example site here . When I add target="_blank" to routerLink, it works correctly, but it's not what I want.. It's driving me nuts..

Sidenav container code (in line-performance component called from app.component):

<mat-sidenav-container>
    <mat-sidenav mode="side" [(opened)]="menuOpened" role="navigation">
      <app-machines></app-machines>
    </mat-sidenav>
    <mat-sidenav-content>
      <router-outlet></router-outlet>
    </mat-sidenav-content>
  </mat-sidenav-container>

Sidenav items (located in machines component):

<mat-nav-list>
  <mat-list-item *ngFor="let machine of machines">
    <a routerLink="/machine/{{machine.id}}">
      <mat-icon [ngClass]="machine.state=='PR'?'green-icon':'red-icon'">stop_circle</mat-icon>  
      {{machine.name}}
    </a>
  </mat-list-item>
</mat-nav-list>

Routes:

const routes: Routes = [
  { path: 'machines', component: MachinesComponent},
  { path: 'machine/:id', component: MachineComponent}
];

Machine template:

<p>To jest strona o indeksie: {{ this.machine.id }}</p>

Whole code on github

Anyone? I'm not even counting on answer why it doesn't work, anything that puts me in the right direction will be a godsend. It's very basic example, everything according to angular's know how files, it really should be working but for some weird reason it doesn't.. I tested it on many machines, in both debug and production environments, the behavior is always the same..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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