我尝试用angular实现spring分页。我试过这个代码:
搜索dto:
public class ClassCategoriesSearchParams {
private String title;
private String type;
private LocalDateTime publishedAt;
}
终结点:
@PostMapping("/find")
public Page<ClassCategoriesFullDTO> search(@Valid ClassCategoriesSearchParams params, Pageable pageable) {
Page<ClassCategoriesFullDTO> list = classCategoriesRestService.findClasses(params, pageable);
return list;
}
public Page<ClassCategoriesFullDTO> findClasses(ClassCategoriesSearchParams params, Pageable pageable) {
Specification<Product> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (params.getTitle() != null) {
predicates.add(cb.equal(root.get("title"), params.getTitle()));
}
if (params.getType() != null) {
predicates.add(cb.equal(root.get("type"), params.getType()));
}
if (params.getPublishedAt() != null) {
predicates.add(cb.greaterThan(root.get("publishedAt"), params.getPublishedAt()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return classCategoriesService.findAll(spec, pageable).map(classCategoriesMapper::toFullDTO);
}
Angular 代码:
<div class="d-flex justify-content-between p-2">
<ngb-pagination [collectionSize]="totalItems" [(page)]="page" [pageSize]="size" (pageChange)="pageChange($event)">
</ngb-pagination>
<select class="custom-select" style="width: auto" [(ngModel)]="size" (ngModelChange)="sizeChange($event)">
<option [ngValue]="1">1 items per page</option>
<option [ngValue]="2">2 items per page</option>
<option [ngValue]="4">4 items per page</option>
<option [ngValue]="6">6 items per page</option>
</select>
</div>
typescript代码:
export class ClassListComponent implements OnInit {
public page = 0;
public size = 1;
public totalItems = 0;
public productList = [];
public classes = [
{
id: null,
productImage: null,
summary: '',
title: '',
imgSrc: null
}
];
public loading = false;
constructor(
private _classService: ClassService,
private sanitizer: DomSanitizer
) { }
ngOnInit(): void {
this.getClassList();
this.getAllProducts();
}
private getClassList(): void {
this._classService.getCategories().subscribe(
data => {
this.classes = [];
this.classes = Object.values(data);
this.classes.forEach(element => {
this.getCategoryImage(element);
});
},
);
}
public getCategoryImage(element): void {
this.loading = true;
this._classService.getCategoryImage(element.id).subscribe(
data => {
element.imgSrc = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(data));
this.loading = false;
}
);
}
private getAllProducts(): void {
this._classService.getAllProducts(this.page, this.size).subscribe(
response => {
this.productList = [];
this.productList = response.content;
this.totalItems = response.totalElements;
}
);
}
public pageChange(event): void {
this.page = event - 1;
this.getAllProducts();
}
public sizeChange(event): void {
this.size = event;
this.getAllProducts();
}
}
服务:
public getAllProducts(
page?: number,
size?: number
): Observable<GenericListDTO<any>> {
let params = new HttpParams();
if (page !== null) {
params = params.set('page', page.toString());
}
if (size) {
params = params.set('size', size.toString());
}
return this.http.post<GenericListDTO<any>>(`${this.url}/find`, {}, { params });
}
export class GenericListDTO<T> {
content: T[] = [];
pageable: any = {};
totalPages: number;
totalElements: number;
size: number;
numberOfElements: number;
}
我有一个问题:当我设置每页的项目数为1时,为了得到第一个项目,我需要发送param page=0。我可以将页面更改函数的逻辑设置为预期的行为,但我的分页组件将无法正确地聚焦所选页面。也许可以用css覆盖来解决这个问题,但是我认为更干净的解决方案是在be函数中改变它。你知道怎么解决这个问题吗?
2条答案
按热度按时间jdgnovmf1#
注意:这不是答案,只是一个评论
如果您使用的是httpclient,那么post必须
忘记httpparams语法是
http.post(<url>,<obj>,<options>}
,参见文档,第三个参数是options,当您不发送json或需要特殊的头时使用它xtfmy6hx2#
您可以为您的服务使用一个减去的新状态变量,而不是修改
page
变量。或者,spring支持从1开始索引分页。两种配置方式
spring.data.web.pageable.one-indexed-parameters=true
在应用程序属性中通过java配置,修改解析器bean