在 Angular 16 中使用快照的可行且更灵活的替代方案是什么?

问题描述 投票:0回答:1

我一直在使用 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确实发生了变化)。

enter image description here

换句话说,使用它来获取和 use

genre_id
失败:

const genre_id = Number(this.activatedRoute.snapshot.paramMap.get('id'));

问题

  1. 我做错了什么?
  2. 解决此问题最简单、最可靠的方法是什么?
javascript angular typescript
1个回答
1
投票

当您在同一路由的变体之间切换时(仅查询参数发生变化),组件不会重新加载,因此为了处理这种情况,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();
  } 
© www.soinside.com 2019 - 2024. All rights reserved.