如何在Ionic中实现搜索和过滤

问题描述 投票:2回答:3

我从我的项目中本地存储的JSON文件中获取数据。 JSON字符串是一个位置数组,其结构如下:

JSON文件

{
    "locations": [
        {
            "title": "ABC",
            "latitude": -1.2596551,
            "longitude": 36.7066604,
            "routes":["22","23","105","115"],
            "fare":[],
            "matatu":[]
        },
        {
            "title": "Adams Arcade",
            "latitude": -1.3004204,
            "longitude": 36.7770793,
            "routes": ["2","4W","102","24","24C","111"],
            "fare":[],
            "matatu":[]
        },
        {
            "title":"Aga Khan Hospital",
            "latitude":-1.2620125,
            "longitude":36.8186399,
            "routes":["11A","11F","106","107","116"],
            "fare":[],
            "matatu":[]
        }
    ]
}

我没有使用管道动态过滤数据,而是在我的provider中实现了一个函数来处理这个问题。这是代码:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { Geolocation } from '@ionic-native/geolocation';

@Injectable()
export class LocationProvider {

  data: any;

  constructor(public http: Http, public geolocation: Geolocation) {

  }

  load(){

    if(this.data){
      return Promise.resolve(this.data);
    }

    return new Promise(resolve => {
        this.http.get('assets/data/locations.json').map(res => res.json()).subscribe(data => {
          this.data = this.applyHarvesine(data.locations);
          this.data.sort((locationA, locationB) => {
            return locationA.distance - locationB.distance;
          });
          resolve(this.data);
        });
    });

  }

  filterLocations(searchTerm){
    return this.data.filter((location) => {
      return location.title.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1;
    });
  }

}

filterLocations()函数将接受searchTerm并返回仅包含与搜索条件匹配的元素的数组。

这是呈现它的页面的.ts.html代码。

.TS

import { Component } from '@angular/core';
import { IonicPage, NavController } from 'ionic-angular';
import { LocationProvider } from '../../providers/location/location';
import { PlaceDetailsPage } from '../place-details/place-details';


@IonicPage()
@Component({
  selector: 'page-places',
  templateUrl: 'places.html',
})
export class PlacesPage {

  searchTerm: string = '';



  constructor(public navCtrl: NavController, public locations: LocationProvider) {
  }

  ionViewDidLoad() {
    this.setFilteredLocations();
  }

  setFilteredLocations(){
    return this.locations.filterLocations(this.searchTerm);
  }

}

html的

<ion-content>
    <ion-searchbar [(ngModel)]="searchTerm" (ionInput)="setFilteredLocations()"></ion-searchbar>
    <ion-list no-lines>
        <button ion-item *ngFor="let location of locations.data">
            <ion-avatar item-left>
                <ion-icon name="pin"></ion-icon>
            </ion-avatar>
            <h2>{{location.title}}</h2>
            <p>{{location.distance}} km</p>
        </button>
    </ion-list>
</ion-content>

当用户在搜索栏上键入时,将调用qazxsw poi来触发数据过滤。问题是,没有任何反应。

我哪里出错了?我的预感是setFilteredLocation()功能有些不对劲,但我不知道它是什么。

是否存在不涉及管道的搜索和过滤的替代方法?

angular typescript ionic-framework ionic2 ionic3
3个回答
8
投票

你做错了。

  1. 你做setFilteredLocation()。它对你的原始数组(return this.data.filter(...))没有影响。它只返回一个新数组,不会更改为this.data。请参阅过滤器this.data
  2. 如果您想更改数据,则需要添加:function doc。但如果你喜欢这样,你就会陷入其他错误。您的this.data = this.data.filter(...)将在过滤后丢失一些元素,并且在重置过滤器时无法恢复。

所以你应该这样做: 在您的组件中:

this.data

在您的模板中使用allData = []; //Store all data from provider filterData = [];//Store filtered data ionViewDidEnter(){ this.allData = this.locations.data; this.filterData = this.allData; } setFilteredLocations(){ this.filterData = this.allData.filter((location) => { return location.title.toLowerCase().indexOf(this.searchTerm.toLowerCase()) > -1; }); } 中的filterData:

ngFor

1
投票

哟没有在这里发送<button ion-item *ngFor="let location of filterData"> 。所以尝试如下所示。

html的

$event

.TS

 <ion-searchbar [(ngModel)]="searchTerm" 
(ionInput)="setFilteredLocations($event)"></ion-searchbar>

你可以看到 setFilteredLocations(ev: any){ let val = ev.target.value; if (val && val.trim() !== '') { return this.locations.filterLocations(val); } }


0
投票

使用CLI命令创建管道并复制到代码下方

official sample code here

}

有关更多信息transform(names: any[], terms: string): any[] { if(!names) return []; if(!terms) return names; terms = terms.toLowerCase(); return names.filter( it => { return it.name.toLowerCase().includes(terms); });

© www.soinside.com 2019 - 2024. All rights reserved.