2017-10-16 95 views
1

我从本地存储在项目中的JSON文件中获取数据。 JSON字符串是位置的阵列,其结构是如下所示:如何在Ionic中实现搜索和过滤

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> 

当在搜索栏用户类型,setFilteredLocation()被称为触发数据的滤波。问题是,没有任何反应。

我哪里出错了?我的直觉是setFilteredLocation()函数中有什么不对劲,但我不知道它是什么。

是否有其他方法来搜索和过滤不涉及管道?

+0

我不知道足够的离子来可以肯定,但是不应该在'filterLocations'之前调用'load'?如果没有'data',这将是预期的行为 – EdoPut

回答

1

你做错了。

  1. 你这样做return this.data.filter(...)。它对您的 原点阵列(this.data)没有影响。它只是返回一个新的数组,并且不会更改为this.data。查看过滤器function doc
  2. 如果您想更改数据,您需要添加: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; 
    }); 
} 

而在你的模板ngFor使用筛选数据:

<button ion-item *ngFor="let location of filterData"> 
1

呦没有发送$event在这里。所以请尝试如下所示。

的.html

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

.TS

setFilteredLocations(ev: any){ 
    let val = ev.target.value; 

    if (val && val.trim() !== '') { 
     return this.locations.filterLocations(val); 
    } 

    } 

你可以看到official sample code here

+0

我应该在嵌套在'ionViewDidLoad()'中的'this.setFilteredLocations()'函数中给出什么参数? – mondieki

+0

你不需要它。你可以删除它。 – Sampath

+0

我已经看过它。它不工作。我错过了什么吗? – mondieki