Select 每页的项目到 Angular 并将参数发送到 Spring
Select items per page into Angular and send param to Spring
我正在尝试使用 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>
打字稿代码:
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 时,为了获得第一个项目,我需要发送参数 page = 0。我可以设置页面更改功能的逻辑来执行像预期的那样,但我的分页组件不会正确聚焦所选页面。也许这可以通过一些 css 覆盖来解决,但我认为更清晰的解决方案是在 BE 函数中更改它。您知道如何解决这个问题吗?
您可以为您的服务创建一个新的状态变量,减去一个而不是修改 page
变量。
另外,Spring 支持从 1 开始的索引分页。您可以通过两种方式配置
spring.data.web.pageable.one-indexed-parameters=true
在您的应用程序属性中
- 通过java配置,修改resolver bean
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
resolver.setOneIndexedParameters(true);
注意:这不是答案,只是评论
如果您使用的是 httpClient,post 必须是
this.http.post<GenericListDTO<any>>(`${this.url}/find`, {
page:page,
size:size,
});
忘记 httpParams 语法是 http.post(<url>,<obj>,<options>}
,见 the docs,第三个参数是选项,当你不发送 json 或者你需要一个特殊的 headers
我正在尝试使用 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>
打字稿代码:
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 时,为了获得第一个项目,我需要发送参数 page = 0。我可以设置页面更改功能的逻辑来执行像预期的那样,但我的分页组件不会正确聚焦所选页面。也许这可以通过一些 css 覆盖来解决,但我认为更清晰的解决方案是在 BE 函数中更改它。您知道如何解决这个问题吗?
您可以为您的服务创建一个新的状态变量,减去一个而不是修改 page
变量。
另外,Spring 支持从 1 开始的索引分页。您可以通过两种方式配置
spring.data.web.pageable.one-indexed-parameters=true
在您的应用程序属性中- 通过java配置,修改resolver bean
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
resolver.setOneIndexedParameters(true);
注意:这不是答案,只是评论
如果您使用的是 httpClient,post 必须是
this.http.post<GenericListDTO<any>>(`${this.url}/find`, {
page:page,
size:size,
});
忘记 httpParams 语法是 http.post(<url>,<obj>,<options>}
,见 the docs,第三个参数是选项,当你不发送 json 或者你需要一个特殊的 headers