我一直在使用 Angular 16、TypeScript 和电影数据库 (TMDB) 开发 SPA。
我在处理按类型列出电影功能时遇到了一个奇怪的问题。
In `app\services\movie-service.service.ts` I have:
import { environment } from '../../environments/environment';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { GenreResponse } from '../models/Genre';
@Injectable({
providedIn: 'root'
})
export class MovieService {
constructor(private http: HttpClient) { }
public getAllMovieGenres(): Observable<GenreResponse> {
return this.http.get<GenreResponse>(`${environment.apiUrl}/genre/movie/list?api_key=${environment.apiKey}`);
}
public getMoviesByGenre(id: Number): Observable<MovieResponse> {
return this.http.get<MovieResponse>(`${environment.apiUrl}/discover/movie?api_key=${environment.apiKey}&with_genres=${id}`);
}
}
我在
MoviesByGenre
组件中使用了上述方法:
import { Component } from '@angular/core';
import { GenreResponse, Genre } from '../../models/Genre';
import { MovieResponse, Movie } from '../../models/Movie';
import { MovieService } from '../../services/movie-service.service';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-movies-by-genre',
templateUrl: './movies-by-genre.component.html',
styleUrls: ['./movies-by-genre.component.scss']
})
export class MoviesByGenre {
constructor(
private activatedRoute: ActivatedRoute,
private movieService: MovieService
) { }
public genreName: string | undefined = '';
public movieResponse!: MovieResponse;
public movies: Movie[] | undefined = [];
public genreResponse!: GenreResponse;
public genres: Genre[] | undefined = [];
public getMoviesByGenre(): void {
// Get genre id (from URL parameter)
const genre_id = Number(this.activatedRoute.snapshot.paramMap.get('id'));
// Get genre name from genres array
this.movieService.getAllMovieGenres().subscribe((response) => {
this.genreResponse = response;
this.genres = this.genreResponse.genres;
if (this.genres && this.genres.length) {
let currentGenre = this.genres.find(genre => genre.id === genre_id);
if (currentGenre) {
this.genreName = currentGenre.name || '';
this.movieService.defaultTitle = this.genreName;
}
}
});
// Get movies by genre id
this.movieService.getMoviesByGenre(genre_id).subscribe((response) => {
this.movieResponse = response;
this.movies = this.movieResponse.results;
})
}
ngOnInit() {
this.getMoviesByGenre();
}
}
每当我显示某种类型的电影并尝试导航到另一种类型时,例如,从
localhost:4200/by-genre/12
到localhost:4200/by-genre/18
,nre数据都不会加载(即使URL确实发生了变化)。
换句话说,使用它来获取和 use
genre_id
失败:
const genre_id = Number(this.activatedRoute.snapshot.paramMap.get('id'));
当您在同一路由的变体之间切换时(仅查询参数发生变化),组件不会重新加载,因此为了处理这种情况,Angular Router 提供了一个可观察对象,它将在路由参数发生变化时发出通知,这可用于触发重新运行流派获取 API。
在销毁组件期间取消所有订阅总是一个好主意
public getMoviesByGenre(genre_id: any): void {
// Get genre id (from URL parameter)
// Get genre name from genres array
this.subscription.add(
this.movieService.getAllMovieGenres().subscribe((response) => {
this.genreResponse = response;
this.genres = this.genreResponse.genres;
if (this.genres && this.genres.length) {
let currentGenre = this.genres.find(genre => genre.id === genre_id);
if (currentGenre) {
this.genreName = currentGenre.name || '';
this.movieService.defaultTitle = this.genreName;
}
}
})
);
// Get movies by genre id
this.subscription.add(this.movieService.getMoviesByGenre(genre_id).subscribe((response) => {
this.movieResponse = response;
this.movies = this.movieResponse.results;
}));
}
ngOnInit() {
this.subscription.add(
this.activatedRoute.params.subscribe((params: Params) => {
const id = params?.id;
this.getMoviesByGenre(id);
})
);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}