Angular使用ngx infinite scroll实现滚动每次加载4条数据求助
问题核心
你当前代码的核心问题有两个:
- 每次滚动触发
onScroll时都重复调用接口,且直接把全量接口返回值赋值给渲染数组categories,自然会一次性展示所有数据 - 没有维护分页偏移量和全量数据源的对应关系,
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
相关产品推荐
相关产品推荐

