我应该如何在这个 Angular 16 应用程序的方法中使用 @HostListener?

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

我一直在使用 Angular 16、TypeScript 和电影数据库 (TMDB) 开发 SPA。

我需要在其中一个组件上执行“无限滚动”功能。

为此目的,我有:

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 genreId = Number(this.activatedRoute.snapshot.paramMap.get('id'));

    const maxPage: number = 10;
    let pageNumber: number = 1;
    let isLoading: boolean = false;

    // 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 === genreId);
        if (currentGenre) {
          this.genreName = currentGenre.name || '';
          this.movieService.defaultTitle = this.genreName;
        }
      }
    });

    // Get movies by genre id
    this.movieService.getMoviesByGenre(genreId, pageNumber).subscribe((response) => {
      this.movieResponse = response;
      this.movies = this.movieResponse.results;

      @HostListener('window:scroll', ['$event'])
       onWindowScroll(event) {
        if (window.innerHeight + window.scrollY >= document.body.offsetHeight &&! isLoading) {
          if (pageNumber < maxPage) {
            isLoading = true;
        
            // Push into the movies array
            this.movies?.push(...this.movies);
        
            // Increment page number
            pageNumber++;
        
            isLoading = false;
          }
        }
      }
    })
  }

  ngOnInit() {
    this.activatedRoute.params.subscribe(() => {
      this.getMoviesByGenre();
    });
  }

  ngOnDestroy() {
    this.movieService.defaultTitle = '';
  }

}

问题

我没想到

@HostListener
在我的
getMoviesByGenre()
方法中会失败,但它确实失败了。

它抛出此错误:

TS1146: Declaration expected.
@HostListener('window:scroll', ['$event'])

问题

  1. 我做错了什么?
  2. 除了使用
    @HostListener
    有可行的替代方法吗?
javascript angular typescript
1个回答
0
投票

我们需要获取可滚动 div 的

ViewChild

@ViewChild('scroller') scroller!: ElementRef<any>;

然后在

ngAfterViewInit
中,我们可以使用rxjs
fromEvent
来监听滚动并应用你需要的逻辑

ngAfterViewInit() {
    if(scroller?.nativeElement) {
        // for window or anything else
        // fromEvent(window, 'scroll')
        // for some div
        fromEvent(scroller.nativeElement, 'scroll').pipe(
            startWith(0), 
            map(x => window?.scrollY), 
            distinctUntilChanged(),
        ).subscribe((scrollPos: any) => {
            // apply logic here!
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.