如何在基于 OpenApi 的 Angular (Ionic) 中使用过滤器?

How to use a filter in Angular (Ionic) based on OpenApi?

目前在我的 Ionic 应用程序中,我使用 ng2-search-filter 来过滤列表中的数据。但是,我的目标是在后端进行过滤,并将过滤后的数据传递给前端。

我使用 OpenApi 3.0 作为后端和前端的接口。在这个界面我有两个方法:

  1. getAllCarports()(获取所有车棚)。

  2. getCarportLocationsByIdAndName(carportNameAndExternalId: string)(获取过滤后的车棚)。

我的列表-客户-service.service.ts

public getAllCarports() {
    return this.service.getAllCarports();
}
public getCarportLocationsByIdAndName(carportNameAndExternalId: string){
    return this.serviceFilter.getStructureCarportsByIdAndName(carportNameAndExternalId);
}

我当前的搜索栏:

<ion-searchbar
    [(ngModel)]="searchTerm"
    showCancelButton="focus"
    animated>
</ion-searchbar>

我当前的列表:

<ion-list id="list">
    <ion-item id="list-item" button *ngFor="let carport of carports | orderByCarportName | filter: searchTerm
              | paginate: {itemsPerPage: 8, currentPage: cp}"  class="listMargin" (click)="openCarport(carport.id)">
        <ion-label>{{carport.id}}</ion-label>
        <ion-label>{{carport.carportName}}</ion-label>
    </ion-item>
</ion-list>

加载页面时,应照常返回完整列表 (getAllCarports())。但是,如果您在搜索栏中输入内容,则应执行方法 getCarportLocationsByIdAndName(carportNameAndExternalId: string)。最好在键入时不断更新列表。有没有人有解决方案或方法?到目前为止我还没有在网上找到合适的东西。

更新 1

@Query("SELECT d FROM CarportLocationEntityView d WHERE d.externalId LIKE %:filterCriteria% OR lower(d.carportName) LIKE lower(concat('%', :filterCriteria,'%')) ")
List<CarportLocationEntityView> filterCarportList(@Param("filterCriteria") String filterCriteria);

更新 2

<ion-searchbar (ionChange)="onChange($event)"
                        [(ngModel)]="filterTerm"
                        showCancelButton="focus"
                        animated>
</ion-searchbar>

<ion-row>
   <ion-col size="12">
       <ion-list id="list">
         <ion-item id="list-item" button *ngFor="let carport of carports | orderByCarportName 
              | paginate: {itemsPerPage: 8, currentPage: cp}"  class="listMargin" (click)="openCarport(carport.id)">
          <ion-label>{{carport.id}}</ion-label>
          <ion-label>{{carport.carportName}}</ion-label>
         </ion-item>
       </ion-list>
     </ion-col>
</ion-row>
onChange(event) {
    const filterTerm = event.target.filterTerm
    if (filterTerm === '') {
      this.listClientService.getAllCarportNamesWithId()
    } else {
      this.listClientService.getCarportLocationsByIdAndName(filterTerm)
    }
}

首先,由于这两种方法都加载了一个车棚列表,因此您应该将它们结合起来。只需添加参数,如果未设置(空),则全部加载,否则进行相应过滤。这可能如下所示

而不是 ngModel,要对 ion-searchbar 的输入更改做出反应,您可以挂接到 ionics ionChange 并简单地向那里发送请求。随着响应覆盖您保存在 .ts 文件中的车棚阵列(此处使用的 *ngFor="let carport of carports)。

该列表将在键入时更新,因为您会在每次完成请求时覆盖该数组。请注意,您应该去抖动,否则您将不必要地向您的后端发送垃圾邮件。

更新1
如果您无法更新后端,只需对给定的搜索栏输入值使用正确的 api 调用即可。

<ion-searchbar (ionChange)="onChange($event)" ... </ion-searchbar>
onChange(event) {
    // log "event", it should be an object which contains the value of the searchbar but i'm unsure of it's properties rn
    const value = event.target.value // not 100% sure if correct
    if (value === '') {
        getAllCarports()
    } else {
        getCarportLocationsByIdAndName(value)
    }
}

更新2
在你的 ts 文件中创建一个 observable 并将你的车棚服务的结果分配给它。

carports: Observable<Carports[]>; // use the type that is returned by the service

... {
    ...
    this.carports = this.listClientService.getAllCarportNamesWithId()
}

对车棚使用关键字 async 来表示这将异步加载并更新。

*ngFor="let carport of carports | async ...