Angular中如何给路由传递参数

How to pass parameters to the route in Angular

我正在探索 Angular。我正在尝试一些基本概念,例如路由、Observables(并订阅它们)、发出 HTTP 请求和路由参数。我创建了一个非常基本的场景,我正在向 JSONPlaceholder 发出 HTTP GET 请求以获取所有相册。我为此创建了一个服务。我添加了:

<a [routerLink]="['albums', album.id]">{{album.title}}</a>

到专辑标题,当我点击一个标题时,我应该被路由到该特定专辑的详细视图。我也会向您展示我的代码,但我认为 stackblitz 会更有意义。这是代码:

album-detail.component.ts

import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AlbumService } from './albums.service';
import { IAlbum } from './album';

@Component({
  template: './album-detail.component.html'
})
export class AlbumDetailComponent {

  album: IAlbum;

  constructor(private _route: ActivatedRoute, private _albumService: AlbumService) {}

  ngOnInit(): void {
    const id=+this._route.snapshot.paramMap.get('id');
    console.log("called for: "+id);
    this.getAlbumById(id);
  }

  getAlbumById(id: number) {
    this._albumService.getAlbumById(id).subscribe({
      next: album => this.onAlbumRetrieved(album)
    })
  }

  onAlbumRetrieved(album: IAlbum): void {
    this.album = album;
  }
}

album.module.ts

import { NgModule } from '@angular/core';
import { AlbumListComponent } from './albums-list.component';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { AlbumDetailComponent } from './album-detail.component';


@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
    RouterModule.forChild([
      {path: 'albums', component: AlbumListComponent},
      {path: 'albums/:id', component: AlbumDetailComponent},
    ])
  ],
  declarations: [ 
    AlbumListComponent,
    AlbumDetailComponent
  ]
})
export class AlbumModule { }

我的get请求也成功了,但是我的路由有问题:

您需要进行 2 处更改:

专辑中-detail.component.ts:

templateUrl: './album-detail.component.html'

专辑中-list.component.html:

<a [routerLink]="[album.id]">{{album.title}}</a>

您只需进行这些更改。

在album.module.ts

 RouterModule.forChild([
    {path: 'albums', component: AlbumListComponent},
    {path: 'albums/album/:id', component: AlbumDetailComponent},
 ])

相册中-detail.component.ts

@Component({
  templateUrl: './album-detail.component.html'
})

检查这两个文件的更新代码。

album.module.ts

import { NgModule } from '@angular/core';
import { AlbumListComponent } from './albums-list.component';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { AlbumDetailComponent } from './album-detail.component';


@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
    RouterModule.forChild([
      {path: 'albums', component: AlbumListComponent},
      {path: 'albums/album/:id', component: AlbumDetailComponent},
    ])
  ],
  declarations: [ 
    AlbumListComponent,
    AlbumDetailComponent
  ]
})
export class AlbumModule { }

专辑-detail.component.ts

import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { AlbumService } from './albums.service';
import { IAlbum } from './album';

@Component({
  templateUrl: './album-detail.component.html'
})
export class AlbumDetailComponent {

  album: IAlbum;

  constructor(private _route: ActivatedRoute, private _albumService: AlbumService) {}

  ngOnInit(): void {
    const id=+this._route.snapshot.paramMap.get('id');
    console.log("called for: "+id);
    this.getAlbumById(id);
  }

  getAlbumById(id: number) {
    this._albumService.getAlbumById(id).subscribe({
      next: album => this.onAlbumRetrieved(album)
    })
  }

  onAlbumRetrieved(album: IAlbum): void {
    this.album = album;
  }
}

如有任何疑问,请告诉我。

您的 AppModule 没有注册相册路线。导入 AlbumModule 不会注册您尝试在其中注册的路由。

您可以通过以下方式处理专辑路线:

  1. 通过延迟加载模块来委派相册路由的责任。
  2. 在您的应用模块中注册专辑路由

对于这个答案来说,延迟加载有点矫枉过正,您可以单独阅读。

此处的简单解决方案是将路线从 AlbumModule 移动到 AppModule:

RouterModule.forRoot([
  {path: 'home', component: HomeComponent},
  {path: 'albums', component: AlbumListComponent},
  {path: 'albums/:id', component: AlbumDetailComponent},
  {path: '', redirectTo: 'home', pathMatch: 'full'},
])

您应该使路由器 link 成为绝对路由器(而不是相对于当前路由),方法是在它前面加上斜杠:

<a [routerLink]="['/albums', album.id]">{{album.title}}</a>

演示:https://stackblitz.com/edit/angular-dyq5wb

请注意,我还更新了 AlbumDetailComponent:

templateUrl: './album-detail.component.html'.