【问题标题】:How to filter the data based on searchbar in Ionic3 and Angular5如何根据 Ionic 3 和 Angular 5 中的搜索栏过滤数据
【发布时间】:2018-11-10 19:51:29
【问题描述】:

我有产品 api。在我的 search.html 页面上,我将显示从 json 文件中获取的所有产品的名称。如何根据 search.html 页面中的搜索栏获得名称。我使用了 Ionic 搜索栏组件,但它不起作用。请帮我。如果此功能有任何可用的替代方案,也请在此处发布。

search.ts

import { Component } from '@angular/core';
import { NavController} from 'ionic-angular';
import { ApiService } from '../../services/api.service';

@Component({
  selector: 'page-search',
  templateUrl: 'search.html'
  // styleUrls: ['search.scss']
})
export class SearchPage {
  searchQuery: string = '';
  items: any[];
  constructor(public navCtrl: NavController, private apiService: ApiService) {
     this.initializeItems();
  }

  initializeItems() {
    this.apiService.productsCall().subscribe(response => {
      //console.log(response);
      if(response['status'] == 200) {
        // this.data=response['response'];
        this.items = response['response'];
        console.log(this.items);
      } else if(response['status'] == 500) {
        console.log(response['error'].sqlMessage);

      }
    });
  }  

  getItems(ev: any) {
    // Reset items back to all of the items
    this.initializeItems();

    // set val to the value of the searchbar
    let val = ev.target.value;

    // if the value is an empty string don't filter the items
    if (val && val.trim() != '') {
      this.items = this.items.filter((item) => {
        return (item['name'].toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
    }
  }
}

search.html

<ion-content padding>
  <ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>

  <ion-list no-lines>

    <ion-item *ngFor="let item of items">
        <ion-label>{{item.name}}</ion-label>
        <ion-avatar item-right>
            <img src='../assets/imgs/medicalStore.png'>
        </ion-avatar>

        <ion-checkbox item-left></ion-checkbox>
    </ion-item>
</ion-list>

</ion-content>

json 文件

{
"status":200,
"error":null,
"response":[
{
"product_id":1,"name":"knee cap","price":1290,"weight":0.4,"short_desc":"Neck Pain Relief Cervical Soft Pillo"
},
{
"product_id":2,"name":"soft pillow","price":1299,"weight":0.3,"short_desc":"Neck Pain Relief Cervical Soft Pillow "
}
]
}

【问题讨论】:

    标签: angular typescript ionic-framework filter


    【解决方案1】:

    所以这是一种可能的方法(不完整)......也许我过度设计了这个问题。

    现在,我们可以将查询和数据都存储为 Observable,而不是重新查询或诸如此类。虽然 observable 存储了原始值,但我们可以使用各种 lettable 运算符,例如 mergeMapmap 函数。

    map 运算符让我们可以修改从可观察对象发出的值,同时将原始值保留在可观察对象本身中。 mergeMap 允许我们有效地合并两个 observables。在这种情况下是_searchQuery_items。此外,我们还可以通过在模板中使用 async 管道来避免订阅这些 observable。

    如果可能,我建议不要使用订阅。虽然有用,但我注意到您从未退订。这意味着订阅将保持活动状态,并且当您一次又一次地调用initializeItems 函数时,您将实例化许多订阅。虽然从技术上讲 HTTP 请求不是问题(因为它们会自行终止),但最好了解/记住这一点。

    如果还有其他事情请告诉我!

    search.ts

    import { Component } from '@angular/core';
    import { BehaviorSubject, Observable } from 'rxjs';
    import { mergeMap, map } from 'rxjs/operators';
    import { NavController } from 'ionic-angular';
    import { ApiService } from '../../services/api.service';
    
    @Component({
      selector: 'page-search',
      templateUrl: 'search.html'
    })
    export class SearchPage {
      private _searchQuery: BehaviorSubject<string> = new BehaviorSubject<string>('');
      private _items: Observable<any[]>;
    
      constructor(public navCtrl: NavController, private apiService: ApiService) {
        this._initializeItems();
      }
    
      get items(): Observable<any[]> {
        return this._searchQuery.pipe(mergeMap((query: string) => {
          return this._items.pipe(map((items: any[]) => {
            if (query && query.trim() != '') {
              return items.filter((item) => {
                return (item['name'].toLowerCase().indexOf(query.toLowerCase()) > -1);
              });
            } else {
              return [];
            }
          }))
        })).asObservable();
      }
    
      private _initializeItems() {
        this._items = this.apiService.productsCall()
          .pipe(map((response) => {
            if (response['status'] == 200) {
              return response['response'];
            } else if (response['status'] == 500) {
              console.log(response['error'].sqlMessage);
              return [];
            }
          }));
      }
    
      public updateQuery(ev: any) {
        // set val to the value of the searchbar
        const val: string = ev.target.value;
        this._searchQuery.next(val);
      }
    }
    

    search.html

    <ion-content padding>
      <ion-searchbar (ionInput)="updateQuery($event)"></ion-searchbar>
    
      <ion-list no-lines>
    
        <ion-item *ngFor="let item of items | async">
            <ion-label>{{item.name}}</ion-label>
            <ion-avatar item-right>
                <img src='../assets/imgs/medicalStore.png'>
            </ion-avatar>
    
            <ion-checkbox item-left></ion-checkbox>
        </ion-item>
    </ion-list>
    
    </ion-content>
    

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 2019-03-16
      • 2018-06-15
      • 2018-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      相关资源
      最近更新 更多