You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 13.3.10无限滚动求助:实现加载组件而非图片的功能

Angular 13.3.10 手动实现组件无限滚动方案

既然ngx-infinite-scroll没达到预期,直接手动实现更可控,以下是针对加载组件的无限滚动实现步骤:

1. 基础配置与模板结构

先在组件中定义核心变量,模板里渲染列表组件和加载提示:

组件类初始代码

import { Component, HostListener, OnInit, OnDestroy } from '@angular/core';

@Component({
  selector: 'app-infinite-scroll',
  templateUrl: './infinite-scroll.component.html',
  styleUrls: ['./infinite-scroll.component.css']
})
export class InfiniteScrollComponent implements OnInit, OnDestroy {
  // 列表数据
  itemList: any[] = [];
  // 当前页码
  currentPage = 1;
  // 每页条数
  pageSize = 10;
  // 是否正在加载
  isLoading = false;
  // 是否已加载全部数据
  hasMore = true;

  ngOnInit(): void {
    // 初始化加载第一页数据
    this.loadMore();
  }

  ngOnDestroy(): void {
    // 组件销毁时可清理滚动监听(window监听用HostListener会自动处理,自定义容器监听需手动移除)
  }
}

模板代码

<!-- 滚动容器,需设置固定高度/最大高度 + overflow:auto -->
<div class="scroll-container">
  <!-- 渲染自定义组件,这里用app-item作为示例 -->
  <app-item *ngFor="let item of itemList" [itemData]="item"></app-item>

  <!-- 加载提示 -->
  <div class="loading-tip" *ngIf="isLoading">加载中...</div>
  <div class="no-more-tip" *ngIf="!hasMore && !isLoading">已加载全部</div>
</div>

样式代码

.scroll-container {
  max-height: 600px; /* 根据需求设置高度 */
  overflow-y: auto;
}

.loading-tip, .no-more-tip {
  text-align: center;
  padding: 16px;
  color: #666;
}

2. 实现滚动触底检测

通过监听滚动事件,判断是否到达加载阈值:

方式一:监听window滚动(适合整页滚动场景)

在组件类中添加HostListener:

@HostListener('window:scroll', [])
onWindowScroll(): void {
  if (this.isLoading || !this.hasMore) return;

  // 计算滚动位置
  const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
  const clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
  const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

  // 距离底部200px时触发加载
  if (scrollTop + clientHeight >= scrollHeight - 200) {
    this.loadMore();
  }
}

方式二:监听自定义容器滚动(适合局部滚动场景)

如果是容器内滚动,需要获取容器元素并监听scroll事件:

import { ElementRef, ViewChild } from '@angular/core';

// 在组件类中添加
@ViewChild('scrollContainer') scrollContainer!: ElementRef<HTMLDivElement>;
private scrollListener?: () => void;

ngOnInit(): void {
  this.loadMore();
  // 绑定容器滚动监听
  this.scrollListener = () => this.onContainerScroll();
  this.scrollContainer.nativeElement.addEventListener('scroll', this.scrollListener);
}

ngOnDestroy(): void {
  // 移除监听
  if (this.scrollListener) {
    this.scrollContainer.nativeElement.removeEventListener('scroll', this.scrollListener);
  }
}

onContainerScroll(): void {
  if (this.isLoading || !this.hasMore) return;

  const container = this.scrollContainer.nativeElement;
  // 计算容器滚动位置
  if (container.scrollTop + container.clientHeight >= container.scrollHeight - 200) {
    this.loadMore();
  }
}

同时修改模板,给容器添加模板引用:

<div #scrollContainer class="scroll-container">
  <!-- 列表内容 -->
</div>

3. 实现数据加载逻辑

编写loadMore方法,模拟或调用真实接口加载数据:

loadMore(): void {
  this.isLoading = true;

  // 模拟接口请求,替换为你的真实API调用
  setTimeout(() => {
    // 生成模拟数据
    const newItems = Array.from({ length: this.pageSize }, (_, i) => ({
      id: (this.currentPage - 1) * this.pageSize + i + 1,
      content: `组件内容 ${(this.currentPage - 1) * this.pageSize + i + 1}`
    }));

    // 合并数据到列表
    this.itemList = [...this.itemList, ...newItems];
    this.currentPage++;

    // 模拟没有更多数据的情况(比如加载到第5页就停止)
    if (this.currentPage > 5) {
      this.hasMore = false;
    }

    this.isLoading = false;
  }, 1000);
}

关键注意事项

  • 滚动容器必须设置固定高度/最大高度和overflow: auto,否则无法触发scroll事件。
  • 加isLoading状态防止重复触发加载,避免接口多次请求。
  • 根据实际场景选择window滚动或容器内滚动的监听方式。
  • 如果列表项高度不固定,触底判断的阈值可以适当调大,提升用户体验。

内容的提问来源于stack exchange,提问作者It's Bender

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 09:15:43