Angular传递多个QueryParams实现API搜索过滤问题及报错排查
Angular Material表格多条件筛选API传参解决方案
第一步:修复类型错误
你当前的TS错误是因为把filter的类型定义成了数组[],但实际要当成对象访问属性,首先需要定义一个筛选参数的接口来规范类型:
在customers.ts中添加筛选接口:
export interface CustomerFilter { name?: string; customerId?: string; vat?: string; database?: string; country?: string; source?: string; // 补充剩余2个筛选条件的字段,字段名需和API预期参数对应 }
第二步:改造服务层动态生成查询参数
修改customers.service.ts,将筛选条件动态追加到请求参数中,只传递非空的筛选值:
getAllCustomersList(currentPage: number, filter: CustomerFilter) { let queryParams = new HttpParams(); queryParams = queryParams.append("page", currentPage.toString()); // 遍历筛选对象,仅添加有值的参数 Object.entries(filter).forEach(([key, value]) => { if (value?.trim()) { // 若API参数名和筛选对象字段名不一致,在这里做映射,比如customerId转成customer_id const apiParamKey = key === 'customerId' ? 'customer_id' : key; queryParams = queryParams.append(apiParamKey, value.trim()); } }); return this.httpClient.get<Customers>(`${environment.apiUrl}customers`, { params: queryParams }); }
第三步:组件层维护筛选状态
修改customers.component.ts,维护筛选对象并优化请求逻辑:
// 初始化空筛选对象 filter: CustomerFilter = {}; currentPage = 1; customerSubscription: Subscription | undefined; loadData() { this.isLoading = true; // 先取消之前的订阅,避免内存泄漏 this.customerSubscription?.unsubscribe(); this.customerSubscription = this.customersServcice.getAllCustomersList(this.currentPage, this.filter).subscribe( data => { this.dataSource.data = data._embedded.customers; setTimeout(() => { // Angular分页器pageIndex从0开始,和API的page(从1开始)做对应 this.paginator.pageIndex = this.currentPage - 1; this.paginator.length = data.total_items; }); this.isLoading = false; }, () => { this.isLoading = false; // 可添加错误提示逻辑 } ); } filterChanged(field: keyof CustomerFilter, value: string) { this.filter[field] = value; // 筛选后重置到第一页 this.currentPage = 1; this.loadData(); }
第四步:模板层绑定筛选字段
修改customers.component.html,将每个输入框绑定到筛选对象的对应属性,并传递字段名给事件:
<mat-toolbar class="crm-filters-toolbar mat-elevation-z8"> <mat-toolbar-row> <span>Filter</span> </mat-toolbar-row> <mat-toolbar-row> <mat-form-field appearance="outline"> <mat-label>Name, email...</mat-label> <input matInput [(ngModel)]="filter.name" (keyup)="filterChanged('name', $event.target.value)" placeholder="Name, email..."> </mat-form-field> <mat-form-field appearance="outline"> <mat-label>Customer ID</mat-label> <input matInput [(ngModel)]="filter.customerId" (keyup)="filterChanged('customerId', $event.target.value)" placeholder="Customer ID"> </mat-form-field> <mat-form-field appearance="outline"> <mat-label>VAT</mat-label> <input matInput [(ngModel)]="filter.vat" (keyup)="filterChanged('vat', $event.target.value)" placeholder="VAT"> </mat-form-field> <mat-form-field appearance="outline"> <mat-label>Database</mat-label> <input matInput [(ngModel)]="filter.database" (keyup)="filterChanged('database', $event.target.value)" placeholder="Database"> </mat-form-field> <mat-form-field appearance="outline"> <mat-label>Country</mat-label> <input matInput [(ngModel)]="filter.country" (keyup)="filterChanged('country', $event.target.value)" placeholder="Country"> </mat-form-field> <mat-form-field appearance="outline"> <mat-label>Source</mat-label> <input matInput [(ngModel)]="filter.source" (keyup)="filterChanged('source', $event.target.value)" placeholder="Source"> </mat-form-field> <!-- 补充剩余2个筛选输入框 --> </mat-toolbar-row> </mat-toolbar> <div class="table-container"> <table mat-table [dataSource]="dataSource"> <!-- table rows and columns... --> </table> </div>
额外注意
- 确保在组件所属的模块中导入
FormsModule,否则[(ngModel)]无法生效:import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ // ...其他模块 FormsModule ] }) export class CustomersModule { } - 若API支持多字段模糊搜索(比如name和email共用一个参数),可在
filterChanged中合并对应字段的值再传递。
内容的提问来源于stack exchange,提问作者weinde
相关产品推荐
相关产品推荐

