ionic 2 фильтр бокового меню для массива на странице

В настоящее время я столкнулся с проблемой с моим Ionic-приложением. Я пытаюсь отфильтровать ионные карты на странице из бокового меню, определенного из (app.html). Это школьный проект для моей программы стажировки, и я был бы очень признателен за помощь. Страница выглядит так: Это моя страница с массивом для фильтрации и Это мой фильтр бокового меню

Мой код для страницы массива выглядит следующим образом, заранее спасибо:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, MenuController } from 'ionic-angular';
import { LocationsPage } from "../locations/locations";
import { AngularFireAuth } from "angularfire2/auth";
import { ToastController } from "ionic-angular";
import { RestPage } from "../rest/rest";
/**
 * Generated class for the ContentPage page.
 *
 * See http://ionicframework.com/docs/components/#navigation for more info
 * on Ionic pages and navigation.
 */
@IonicPage()
@Component({
  selector: 'page-content',
  templateUrl: 'content.html',
})
export class ContentPage {
  modifiedData: any;
  originalData: any;


  constructor(private toast:ToastController,private afAuth: AngularFireAuth,public navCtrl: NavController, public navParams: NavParams, public menuCtrl: MenuController) {
        this.navCtrl = navCtrl;
        this.menuCtrl = menuCtrl;
    // this.menuCtrl.enable(true, 'myMenu');

//array for the display of cards

//properties defined about the cards include:

//name-name of the Restaurant

//image-image to be used for the card

//text-text for the card

//PushPage-for pushing a specific page

//Price - defines price of a restaurant

// Cusisine - defines a restaurants Cuisine

//PAGE: SAME AS PUSHPAGE


    this.originalData=[
      {name:'Fairmont Hotel',image:'assets/images/fairmont.jpg',text:'Lorem Ipsum is simply dummy text of the printing and typesetting industry.', PushPage: 'RestPage',Price: 'low', Cuisine:'Kenyan',Page: RestPage},
      {name:'MarymountHotel',image:'assets/images/fairmont.jpg',text:'Lorem Ipsum is simply dummy text of the printing and typesetting industry.', PushPage: 'RestPage',Price: 'Midrange',Cuisine:'Ethiopian', Page: RestPage}
    ];
    this.modifiedData=JSON.parse(JSON.stringify(this.originalData));
  }


//toast message to welcome a user to the app
  ionViewWillLoad() {
    this.afAuth.authState.subscribe(data =>{
      if(data.email && data.uid){
        this.toast.create({
          message:'welcome to Rest',
          duration: 3000 
        }).present();
      }
    })
  }

  //onclick event
 itemSelected (PushPage) {
  //alert(page);
  var page = this.originalData.filter(function(it) {
    return it.PushPage == PushPage
  })[0].Page
  //alert(page);
   this.navCtrl.push(page);
 }

//reset function
reset(){
  this.modifiedData = JSON.parse(JSON.stringify(this.originalData));
}

//filtering function
filter(){
this.modifiedData=this.modifiedData.filter((rest)=>
{ return rest.Cuisine=='Kenyan'});
}

//toggel menu function
 toggleLeftMenu() {
   this.menuCtrl.toggle('left');
 }

  toggleRightMenu() {
  this.menuCtrl.toggle('right');
 }

 //function that pushes from FAB button to LocationsPage
Locations(){
  this.navCtrl.push(LocationsPage);
}
//function directing to the rest page that contains restaurant details
Rest(){
  this.navCtrl.push(RestPage);
}
}

Код для бокового меню следующий:

<ion-menu side="left"  [content]="content">
  <ion-header id="background">
    <ion-avatar item-start>
      <img src="">
    </ion-avatar>
  </ion-header>

  <ion-content>
    <ion-list>


      <button ion-item (click)="openPage(homePage)">
        Reservations
      </button>
      <button ion-item (click)="openPage(friendsPage)">
        Settings
      </button>

    </ion-list>
  </ion-content>

</ion-menu>


<!-- second sidemenu -->

<ion-menu side="right"  [content]="content">
    <ion-header id="background2">

  </ion-header>
<ion-content>
  <ion-item>
    <p>Im looking for:</p>
    <ion-label stacked>Cuisine:</ion-label>
   <ion-select [(ngModel)]="gender">
    <ion-option value="K">Kenyan</ion-option>
    <ion-option value="E">Ethiopian</ion-option>
    <ion-option value="I">Indian</ion-option>
    </ion-select>
  </ion-item>

  <ion-item>
    <ion-label stacked>Vibe:</ion-label>
    <ion-select [(ngModel)]="Vibe">
      <ion-option value="C">Chilled</ion-option>
      <ion-option value="F">Formal</ion-option>
    </ion-select>
  </ion-item>

  <ion-item>
    <ion-label stacked>price:</ion-label>
    <ion-select [(ngModel)]="Price">
      <ion-option value="L">Low</ion-option>
      <ion-option value="M">Midrange</ion-option>
      <ion-option value="H">HighPriced</ion-option>
    </ion-select>
  </ion-item>

  <!-- grid for placing the buttons -->
  <!-- first grid for the reset button -->
  <ion-grid>
    <ion-row>
      <ion-col col-6>
      <button ion-button color="secondary" outline (click)='reset()'>Reset</button>
      </ion-col>

      <!-- second column for the apply button -->
      <ion-col col-6>
        <button ion-button color="secondary"  outline (click)='filter(rest)' >Apply </button>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>
</ion-menu>

<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
<ion-nav [root]="rootPage" #content ></ion-nav>

person Dev Hig    schedule 15.08.2017    source источник
comment
нет, ошибки нет, просто я довольно давно застрял в том, как реализовать систему фильтрации в приложении. Кажется, я не могу найти способ связать фильтр бокового меню с массивом.   -  person Dev Hig    schedule 15.08.2017


Ответы (1)


Создайте объект-оболочку для вашего filter f.e. {price: string, vibe: string}, где вы отслеживаете выбранные фильтры.

src / models / filter.model.ts

export class FilterWrapper {
   price: string = "NONE"; //default value
   vibe: string = "NONE";
   cuisine: string = "NONE";
}

src / app / app.component.ts

Теперь, когда фильтр изменяется (в app.component.ts), сделайте вашу функцию такой:

import { Events } from 'ionic-angular';
import { FilterWrapper } from '../models/filter.model';

@Component({...})
export class AppComponent{
    filterWrapper: FilterWrapper;
    constructor(events: Events) { 
       // creates a filterwrapper {price: "NONE", vibe:"NONE",cuisine:"NONE"}
       this.filterWrapper = new FilterWrapper();
    }

    saveFilters() {
      this.events.publish('filters:changed', this.filterWrapper);
     // where this.filterWrapper contains the selected filters (ngModel on select list f.e.)
    }
}

src / app / app.component.html

<!-- only 1 example provided -->

<ion-select [(ngModel)]="filterWrapper.cuisine">
    <ion-option value="K">Kenyan</ion-option>
    <ion-option value="E">Ethiopian</ion-option>
    <ion-option value="I">Indian</ion-option>
    </ion-select>
</ion-item>

Теперь послушайте это событие изменения на странице вашего массива:

src / pages / content.component.ts

import { Events } from 'ionic-angular';
import { FilterWrapper } from '../models/filter.model';

export class ContentPage {

    filterWrapper: FilterWrapper = new FilterWrapper();
    allItems = []; // your 'all' item list to display, normally filled. 

    constructor(events: Events) {
      events.subscribe('filters:changed', filter => {
          this.filterWrapper = filter;
      }
    }

    // returns true if the item matches the selected filters
    // yes could be more efficient but this is more comprehensive.
    matchesFilters(item: any) {
       let filter = this.filterWrapper;
       let result: boolean = false;

       // default true in case cuisine is "NONE"
       let cuisineResult = true;
       if(filter.cuisine != "NONE") {
          cuisineResult = filter.cuisine == item.cuisine;
       }

       let vibeResult = true;
       if(filter.vice != "NONE") {
         vibeResult = filter.vibe == item.vibe;
       }

      let priceResult = true;
      if(filter.price != "NONE") {
        priceResult = filters.price == item.price;
      }

      // true if all are or false if one of them is false
      result = (cuisineResult && vibeResult && priceResult);
      return result;
    }
}

На странице src / pages / content.component.html у вас будет что-то вроде:

<ion-item *ngFor="let item of allItems">

Теперь, поскольку у вас не может быть 2 * на 1 элементе, что немного раздражает, обходной путь будет заключаться в следующем:

<!-- loop through the list and create an item for all of them -->
<div *ngFor="let item of allItems">
 <!-- dont show the item if it doesn't match the filters --> 
 <ion-item *ngIf="!matchesFilters(item)>
   <!-- dont put your *ngIf on the <ion-card> else the <ion-item> will still be created and that takes up space in your page -->
   <ion-card>
    ....
person Ivar Reukers    schedule 15.08.2017
comment
привет, еще раз спасибо за уделенное время. Вроде новичок в ionic, так что у меня вроде бы проблемы с вашей логикой, не могли бы вы объяснить это ... им, например, неясно, следует ли определять оболочку фильтра в app.html или в app.components.ts и что будет последней функцией, запускающей фильтр. - person Dev Hig; 16.08.2017
comment
@DevHig Привет, Дев, я обновил свой ответ. Фильтр-обертка будет действовать как объект, который вы можете просто создать с помощью export class. Последняя функция для установки фильтров в качестве текущего выбора и отображения / скрытия элементов - saveFilters() в app.component.ts. Надеюсь, вы понимаете, что я здесь делаю, иначе я более чем готов уточнить. - person Ivar Reukers; 16.08.2017
comment
@DevHig без проблем. Какой массив нужно передать фильтру? И не могли бы вы поделиться своим JSON, из которого вы создаете свои элементы? Потому что я просто предположил, что ваш список элементов имеет те же свойства, что и ваш фильтр, но это может быть не так. (пожалуйста, отредактируйте свой вопрос и добавьте его, в комментариях будет беспорядок) - person Ivar Reukers; 18.08.2017
comment
@DevHig, что означает, что ни один элемент не передает функцию matchesFilters или вызывает ошибки при загрузке страницы. - person Ivar Reukers; 18.08.2017