Панель поиска с фильтром и из данных JSON с Ionic 2

Я очень новичок в Typescript и Ionic 2, и я пытаюсь отфильтровать ответ json с помощью панели поиска Ionic 2.

Это мой код:

import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';



@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {

  posts: any;
  private searchQuery: string = '';
  private items: string[];
  constructor(private http: Http) {

    this.initializeItems();

    this.http.get('https://domain.co/open.jsonp').map(res => res.json()).subscribe(data => {
        this.posts = data;
        console.log(this.posts);

    });

  }

  initializeItems() {
    this.items = this.posts;
  }

  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.toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
    }
  }

}

И разметка:

<ion-header>
  <ion-searchbar (ionInput)="getItems($event)" [debounce]="500" placeholder="Suchen..."></ion-searchbar>
</ion-header>

<ion-content>
  <ion-list>
    <ion-item *ngFor="let post of posts">
      <h1>{{post.storeName}}</h1>
    </ion-item>
  </ion-list>
</ion-content>

Я эта ошибка при поиске:

item.toLowerCase не является функцией

Данные JSON выглядят так:

[
{
storeName: "Avec Hauptbahnhof",
addressLink: "",
phone: "0326223902",
image: "",
description: "",
link: "",
openingHours: [
"05.30 - 22:00",
"05.30 - 22:00",
"05.30 - 22:00",
"05.30 - 22:00",
"05.30 - 22:00",
"06.30 - 22:00",
"7.00 - 22.00"
]
},
{
storeName: "Manor",
addressLink: "",
phone: "0326258699",
image: "",
customer: "",
description: "",
link: "",
openingHours: [
"09.00 - 18.30",
"09.00 - 18.30",
"09.00 - 18.30",
"09.00 - 21:00",
"09.00 - 18.30",
"08.00 - 17.00",
"Geschlossen"
]
}
]

person olivier    schedule 20.08.2016    source источник
comment
https://domain.co/open.jsonp возвращает список строк?   -  person sebaferreras    schedule 20.08.2016
comment
он возвращает объект json   -  person olivier    schedule 20.08.2016
comment
Не могли бы вы добавить в OP, как выглядит этот объект json?   -  person sebaferreras    schedule 20.08.2016
comment
конечно, я редактировал вопрос @sebaferreras   -  person olivier    schedule 20.08.2016
comment
Большое спасибо. Надеюсь, ответ вам поможет :)   -  person sebaferreras    schedule 20.08.2016
comment
@sebaferreras У меня аналогичная проблема с ion-searchbar. Я был бы очень признателен, если бы вы мне помогли с этим. Вот ссылка на мой запрос - stackoverflow.com/questions/59095620/   -  person Akhilesh Pothuri    schedule 29.11.2019


Ответы (2)


Вы получаете эту ошибку, потому что каждый элемент - это не строка, а объект, поэтому вместо выполнения

item.toLowerCase().indexOf(val.toLowerCase()) > -1

Ты должен сделать

item.storeName.toLowerCase().indexOf(val.toLowerCase()) > -1

Также обратите внимание, что, по вашему мнению, вы используете массив posts

*ngFor="let post of posts" 

Но вместо этого вам следует использовать массив items, потому что именно он будет отфильтрован.

  <ion-list>
    <ion-item *ngFor="let item of items">
      <h1>{{item.storeName}}</h1>
    </ion-item>
  </ion-list>

Кроме того, я бы поступил немного по-другому, просто чтобы убедиться, что пользователь может использовать страницу только, когда данные доступны (поскольку вы используете HTTP-запрос для получения Это). Для этого я бы добавил предупреждение о загрузке и удалил бы его, как только HTTP-запрос будет выполнен. Начиная с Ionic2-beta.11, это можно было сделать так:

import { Component } from '@angular/core';
import { NavController, LoadingController } from 'ionic-angular';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';


@Component({
  templateUrl: 'build/pages/home/home.html'
})
export class HomePage {

  private posts: any; // <- I've added the private keyword 
  private searchQuery: string = '';
  private items: any; // <- items property is now of the same type as posts
  constructor(private http: Http, private loadingCtrl: LoadingController) {

    // this.initializeItems(); <- you don't need this anymore

    // Show the loading message
    let loadingPopup = this.loadingCtrl.create({
      content: 'Loading posts...'
    });

    this.http.get('https://domain.co/open.jsonp').map(res => res.json()).subscribe(data => {
        this.posts = data;
        this.initializeItems();

        // Hide the loading message
        loadingPopup.dismiss();
    });
  }

  initializeItems() {
    this.items = this.posts;
  }

  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.storeName.toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
    }
  }

}
person sebaferreras    schedule 20.08.2016
comment
Большое спасибо! :) Как и где вы узнали ionic2 и typescipt? Сейчас я перехожу с ионного 1 на ионный 2. - person olivier; 20.08.2016
comment
Я бы сказал, что лучшее место для изучения Ionic2 - это Ionic2 docs. Вы сэкономите много времени, если прочитаете о компонентах, которые собираетесь использовать в своем проекте, прежде чем запачкаете руки :) - person sebaferreras; 20.08.2016

С той же проблемой, с которой я столкнулся, когда работал в angular 2 с ionic.

В нашем проекте у нас есть один метод для получения всего списка продуктов и отображения элементов с помощью * ngFor.

Всякий раз, когда мы выполняем поиск с использованием ионной панели поиска, вводимый текст поиска будет получен с использованием "event.target.value". Мы должны проверить, совпадает ли поисковый текст в элементах.

Код есть,

   getAllProdcuts(isFrom, searchText){
      this.toDoService.getAllProdcuts().then((res) => {
        this.items = res;
            if(isFrom == 'search') {
                this.items = this.items.filter((item) => {
                    return (item.toLowerCase().indexOf(searchText.toLowerCase()) > -1);
                })
            }
        }, (err) => {

        });
    }

  getItems(ev: any) {

    // 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.getAllProdcuts("search", val);
    }
  }

Здесь мы можем получить отфильтрованные элементы из метода.

Спасибо.!

person Ponmurugan Mohanraj    schedule 17.06.2017