Je récupère des données à partir d'un fichier JSON stocké localement dans mon projet. La chaîne JSON est un tableau d'emplacements, dont la structure est la suivante:
fichier 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":[]
}
]
}
Plutôt que de filtrer les données à la volée avec un tuyau, j'ai implémenté une fonction dans mon provider
pour gérer cela. Voici le code:
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;
});
}
}
La fonction filterLocations()
consiste à prendre searchTerm
et retourne un tableau contenant uniquement les éléments qui correspondent aux critères de recherche.
Voici le code .ts
Et .html
Pour la page où il est rendu.
. 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>
Lorsque l'utilisateur tape dans la barre de recherche, setFilteredLocation()
est appelée pour déclencher le filtrage des données. Le problème est que rien ne se passe.
Où ai-je mal tourné? Mon intuition est que quelque chose ne va pas dans la fonction setFilteredLocation()
, mais je n'ai aucune idée de ce que c'est.
Existe-t-il une approche alternative à la recherche et au filtrage qui n'implique pas de tuyaux?
Tu le fais incorectement.
return this.data.filter(...)
. Cela n'a aucun effet sur votre tableau Origin (this.data
). Il retourne simplement un nouveau tableau et ne modifie pas this.data
. Voir le filtre fonction docthis.data = this.data.filter(...)
. Mais si vous aimez ça, vous tomberez dans une autre erreur. Votre this.data
Perdra un élément après le filtre et il ne pourra pas être rétabli lorsque vous réinitialisez le filtre.Vous devriez donc faire comme ça:
Dans votre composant:
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;
});
}
Et dans votre modèle, utilisez filterData dans ngFor
:
<button ion-item *ngFor="let location of filterData">
Yo n'a pas envoyé le $event
ici. Essayez donc comme indiqué ci-dessous.
. 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);
}
}
Vous pouvez voir le exemple de code officiel ici .
Créer un tuyau à l'aide de la commande CLI et copier le code ci-dessous
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);
});
}
Pour plus d'informations https://androiddhina.blogspot.com/2019/03/ionic-4-search-filter-using-pipe.html