实现可分页到Angular项目的最佳方式



我的数据库中有产品,我在后端应用程序上创建了控制器,经过测试,效果非常好,所以现在我需要在前端实现它。我有一个product.component.ts文件,看起来像这个

import { Component, OnInit } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { debounceTime, switchMap } from "rxjs";
import { ProductService } from "./product.service";
@Component({
selector: 'app-product',
templateUrl: './product.component.html'
})
export class ProductComponent implements OnInit {
products: any[] = [];
productSearchForm!: FormGroup;
page: number = 0;
size: number = 4;
constructor(
private productService: ProductService
) { }
loadMore() {
this.page = this.page+1;
this.productSearchForm.get('searchTerm')?.valueChanges
.pipe(
debounceTime(500),
switchMap(value => {
return this.productService.searchByTermPageable(value, this.page, this.size);
})
).subscribe(data => {
this.products = data;
}, error => {
console.log(error);
// this.products = [];
});
}
ngOnInit(): void {
this.initializeForm();
this.productSearchForm.get('searchTerm')?.valueChanges
.pipe(
debounceTime(500),
switchMap(value => {
return this.productService.searchByTermPageable(value, this.page, this.size);
})
).subscribe(data => {
this.products = data;
}, error => {
console.log(error);
// this.products = [];
});
}
private initializeForm(): void {
this.productSearchForm = new FormGroup({
searchTerm: new FormControl(null)
});
}
}

searchTerm是一个查询参数,用于查找名称以该术语开头的产品。我从文件product.service.ts调用函数,它看起来像这个

import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { environment } from "src/environments/environment";
@Injectable({ providedIn: 'root'})
export class ProductService {
constructor(private httpClient: HttpClient) { }
searchByTerm(searchTerm: string): Observable<any> {
const url = `${environment.apiUrl}product/search/by-name-or-desc?term=${searchTerm}`;
return this.httpClient.get(url);
}
searchByTermPageable(searchTerm: string, page: number, size: number): Observable<any> {
const url = `${environment.apiUrl}product/search/by-name-or-desc?term=${searchTerm}&page=${page}&size=${size}`;
return this.httpClient.get(url);
}
}

当我点击"加载更多"按钮时,我想从数据库中加载接下来的4个产品,但将前4个产品保留在我的html页面上,那么最好的方法是什么?这是我的html页面,我也使用Bulma作为我的css框架

<div class="mt-5">
<form>
<div class="field" [formGroup]="productSearchForm">
<div class="control has-icons-left">
<input class="input" type="text" formControlName="searchTerm" placeholder="Find products">
<span class="icon is-small is-left">
<i class="fas fa-search"></i>
</span>
</div>
</div>
<hr />
</form>
</div>
<div class="columns">
<div class="column" *ngFor="let product of products">
<div class="card">
<div class="card-content">
<div class="media">
<div class="media-content">
<p class="title is-4">{{ product.name }}</p>
<p class="subtitle is-6">{{ product.category?.name}}</p>
</div>
</div>
<div class="content">
{{ product.description }}
</div>
</div>
</div>
</div>
</div>
<button type="button" class="button is-primary" (click)="loadMore()">Load more...</button>

您可以在服务中使用一个新函数,返回页面的元素以及搜索的其他元素。如果您有一个返回分页元素的函数

searchByTermPageable(search:string,page:number,size:number)
{
...
}

有些像

product:any[]=[]  //define an empty array where you store the product
searchOld:string=null  //and a variable to store the search
getData(search:string,page:number,size:number)
{
if (search!=this.searchOld)  //if is a new search
{
this.searchOld=search
this.product=[]
}
return this.searchByTermPageable(search,page,size).pipe(
map((res:any[])=>[...this.product,...res]), //concat the before store product
tap((res:any[])=>{
this.product=res  //store in the product the new array
})
)
}

给你一些像

<div *ngFor="let product of product$|async">
{{product.name}}
</div>
<button (click)="more()">more</button>
pageIndex:number=-1;
product$:Observable<any[]>
more()
{
this.pageIndex++
this.product$=this.dataService.getData("",this.pageIndex,4)
}

另一种解决方案是搜索所有产品并简单使用切片管

<div *ngFor="let product of allProduct$|async |slice:0:(index+1)*pageSize">
{{product.name}}
</div>
<button (click)="index=index+1">more</button>

一litle stack litz

最新更新