【问题标题】:ionic 2 side-menu filter for an array on pageionic 2 侧面菜单过滤器,用于页面上的数组
【发布时间】:2018-01-23 06:06:40
【问题描述】:

我目前在使用 Ionic 应用时遇到问题。我正在尝试从(app.html)定义的侧面菜单中过滤页面上的离子卡。这是我的实习计划的学校项目,我非常感谢您的帮助。 页面如下所示:That is my page with the array to be filteredThis is my side-menu filter

到目前为止,我的数组页面代码如下,在此先感谢:

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>

【问题讨论】:

  • 不,没有错误,只是我在如何在应用程序中实现过滤器系统上卡了很长时间。我似乎找不到将侧面菜单过滤器与数组链接的方法。

标签: ionic-framework ionic2 ionic3 ionic-native


【解决方案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 页面中,您将看到类似以下内容:

&lt;ion-item *ngFor="let item of allItems"&gt;

现在,因为您不能在 1 个项目上拥有 2 个 *,这有点烦人,因此可以采用一种解决方法:

<!-- 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>
    ....

【讨论】:

  • 嗨,再次感谢您的时间。有点像 ionic 的新手,所以我在遵循您的逻辑时遇到了一些麻烦,请您解释一下..im,例如是否在 app.html 或 app.components.ts 上定义过滤器包装器以及什么最后一个函数会触发过滤器吗?
  • @DevHig 嗨,开发者,我更新了我的答案。 filterwrapper 就像一个对象,你可以通过export class 创建它。将过滤器设置为当前选择和显示/隐藏项目的最终功能是saveFilters() in app.component.ts。希望你明白我在这里做什么,否则我更愿意详细说明。
  • @DevHig 没问题。您需要将什么数组传递给过滤器?你能分享你创建项目的 JSON 吗?因为我只是假设您的项目列表与您的过滤器具有相同的属性,但情况可能并非如此。 (请编辑您的问题并将其添加进去,会在 cmets 中变得混乱)
  • @DevHig 这意味着没有项目通过matchesFilters 函数,或者它会导致页面加载错误。
猜你喜欢
  • 1970-01-01
  • 2015-01-07
  • 2016-08-29
  • 2017-11-09
  • 1970-01-01
  • 2017-08-14
  • 1970-01-01
  • 2016-09-07
  • 2020-05-06
相关资源
最近更新 更多