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

Angular使用ngx infinite scroll实现滚动每次加载4条数据求助

问题核心

你当前代码的核心问题有两个:

  1. 每次滚动触发onScroll时都重复调用接口,且直接把全量接口返回值赋值给渲染数组categories,自然会一次性展示所有数据
  2. 没有维护分页偏移量和全量数据源的对应关系,slice逻辑没有落地的载体

修改方案

组件代码调整

import {
  Component, OnInit
} from '@angular/core';
import { APIService } from 'src/app/services/api.service';

@Component({
  selector: 'app-categories',
  templateUrl: './categories.component.html',
  styleUrls: ['./categories.component.css']
})

export class CategoriesComponent implements OnInit {
  isBottom = false
  names = []
  allProducts = [] // 存储全量产品数据
  categories: any = []
  pageSize = 4 // 固定每次加载4条
  currentPage = 1 // 记录当前加载到的页码,初始为1
  constructor(
    private apiService: APIService
  ) { }

  ngOnInit() {
    this.getProductsData()
  }
  
  getProductsData() {
    this.apiService.GetProductData()
      .subscribe((response: any) => {
        this.allProducts = response // 先存全量数据,不要每次滚动重复请求
        // 初始加载第一页4条
        this.categories = this.allProducts.slice(0, this.pageSize)
        this.names = response.map((product: any) => product.title)
      },
        err => console.log(err))
  }

  onScroll() {
    // 已经加载完全部数据直接返回,显示底部提示
    if (this.categories.length >= this.allProducts.length) {
      this.isBottom = true
      return
    }
    console.log('SCROLLED') 
    // 计算当前批次的起止索引
    const startIndex = this.currentPage * this.pageSize
    const endIndex = startIndex + this.pageSize
    // 截取对应批次数据追加到渲染数组
    const nextBatch = this.allProducts.slice(startIndex, endIndex)
    this.categories.push(...nextBatch)
    // 页码累加,为下一次加载做准备
    this.currentPage++
  }
}

模板代码调整

你当前把infiniteScroll指令绑定在独立空div上,容易出现滚动触发异常的问题,建议把指令绑定到产品列表的滚动容器上,删除原来独立的空infiniteScroll节点:

<!-- 把infiniteScroll指令绑定在产品列表的父容器上 -->
<div class="row" infiniteScroll [infiniteScrollDistance]="2"
[infiniteScrollThrottle]="50" (scrolled)="onScroll()">
  <div *ngFor="let cat of categories" class="item" style="width:300px; float:left;">
      <div>
          <div>
              <div>
                  <a href="product.html">
                      <img src="{{cat.image}}" alt="x" class="img-fluid">
                  </a>
              </div>
              <div class="col-12 mb-3">
                  <a href="product.html" class="product-name">{{cat.title}}</a>
              </div>
              <div class="col-12 mb-3">
                  <span class="product-price-old">

                  </span>
                  <br>
                  <span class="product-price">

                  </span>
              </div>
              <div class="col-12 mb-3 align-self-end">
                  <button class="btn btn-outline-dark" type="button"><i
                          class="fas fa-cart-plus me-2"></i>Add to cart</button>
              </div>
          </div>
      </div>
      <br />
  </div>
</div>

如果你的后端接口支持分页查询,不需要一次性拉取全量数据,可以进一步优化逻辑:每次onScroll的时候把当前页码和pageSize传给接口,拿返回的对应页数据直接push到categories即可,不需要维护全量的allProducts数组,性能更好。


内容的提问来源于stack exchange,提问作者Arpit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:24:06