【问题标题】:Filter results with ion-select使用离子选择过滤结果
【发布时间】:2019-04-08 19:09:48
【问题描述】:

我是 ionic 新手,正在学习一些教程并尝试学习和应用其他东西。我认为我想要实现的目标非常简单,但我似乎无法让它发挥作用。

我要做的只是使用 ion-select 元素过滤结果以显示其对应的选择。

所以我所拥有的是这个离子选择,我在哪里使用 ngModel 和 ngFor 来过滤用户应该拥有的选项,一旦用户选择他们的选项,应用程序应该只显示对应的结果,在这种情况下,一项运动(因此,如果用户在离子选择中选择“足球”,则只应显示“足球”离子卡,我在后端连接了那些。

我在这里添加一段代码,但恐怕您可能需要其他代码才能更清楚,所以请告诉我。伙计们干杯!

<ion-content padding>

<ion-item>
  <ion-label>Filter by Sport</ion-label>
  <ion-select [(ngModel)]="list" multiple="true">
    <ion-option *ngFor="let item of list">{{item.sport}}</ion-option>
  </ion-select>
</ion-item>

    <ion-card *ngFor="let item of list">    
      <ion-card-content>
        <ion-card-title>{{item.title}}</ion-card-title>
        <p>Sport: {{item.sport}}</p>
        <p>Participants: {{item.players}}</p>
        <p>When: {{item.when}}</p>
        <p>{{item.description}}</p>
        <p>Location: {{item.location}}</p>
        <button ion-button block (click)="joinEvent(item)">Join!</button>
      </ion-card-content>
    </ion-card>

</ion-content>

编辑:在下面添加了 .ts 代码:

export class JoinEventPage {

  filterListBy$
  filteredList$

    list: IEvent[];
  joined = [];

  constructor(public navCtrl: NavController, 
              public navParams: NavParams, 
              public eventProvider: EventsProvider,
          public joinedEventsProvider: JoinedEventsProvider) {

  }

  ionViewDidEnter(){

    // create observable
    this.filterListBy$ = Observable.from(this.list)
      // pull out just the name of the sport
      .map((a: any) => a.sport)
      // make sure items are distinct
      .distinct()
      // return an array
      .toArray();

    // force the initial filtering of the list
    this.changeCategory([])

    // this.eventProvider.listEvents().subscribe(res=>{
    //  this.list = res;
    // }, error => {
    //  console.log("Error: " + error.message);
    // });

    // this.joinedEventsProvider.getStorage('joined-events').then(res => {
    //   if(res){
    //     this.joined = res;
    //   }
    // });
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad JoinEventPage');
  }

  joinEvent(item){
    for(let event of this.joined){
      if(event.id == item.id){
        console.log("You already joined this event!")
        return;
      }
    }
    this.joined.push(item);
    this.joinedEventsProvider.setStorage('joined-events', this.joined);
  }

  changeCategory(_value) {
    // if nothing selected, show all
    if (!_value.length) {
      return this.filteredList$ = Observable.from(this.list).toArray();
    }

    // if something selected, filter the list based on the item selected which 
    // will be in the array parameter "_value"
    this.filteredList$ = Observable.from(this.list)
      .filter((i) => { return _value.indexOf(i.sport) !== -1 })
      .toArray()
  }

}

解决方案:按照 Aaron 的解决方案,我对 .ts 文件所做的唯一更改如下:

ionViewDidEnter(){

    this.eventProvider.listEvents().subscribe(res=>{
    this.list = res; 

     // create observable
    this.filterListBy$ = Observable.from(this.list)
      // pull out just the name of the sport
      .map((a: any) => a.sport)
      // make sure items are distinct
      .distinct()
      // return an array
      .toArray();

    // force the initial filtering of the list
    this.changeCategory([])

    this.joinedEventsProvider.getStorage('joined-events').then(res => {
        if(res){
          this.joined = res;
        }
      });

    });


  }

【问题讨论】:

  • 更改[(ngModel)]="list" with [(ngModel)]="selectedList" 并为名称selectedList 创建全局变量。而且您的 ion-option 标签没有 [value] 属性。请将此属性添加到您的ion-option 标签。例如:[value]='item.sport'.
  • @Omsl 谢谢,我正在尝试解决您的想法,但没有运气。您可以将示例添加到代码中吗?我在想“列表”仍然需要在那里,因为它包含所有可以过滤的项目,但我知道你的想法是让 selectedList 保存用户选择的项目,我只是无法放置他们工作:(

标签: ionic-framework mobile ionic3


【解决方案1】:

在此处查看完整答案,但亮点如下

https://stackblitz.com/edit/ionic-tkqzr6

  ngOnInit() {
    // create observable
    this.filterListBy$ = Observable.from(this.list)
      // pull out just the name of the sport
      .map((a: any) => a.sport)
      // make sure items are distinct
      .distinct()
      // return an array
      .toArray();

    // force the initial filtering of the list
    this.onChange([])
  }

当用户选择一个选项时,我们调用 onChange

  onChange(_value) {
    // if nothing selected, show all
    if (!_value.length) {
      return this.filteredList$ = Observable.from(this.list).toArray();
    }

    // if something selected, filter the list based on the item selected which 
    // will be in the array parameter "_value"
    this.filteredList$ = Observable.from(this.list)
      .filter((i) => { return _value.indexOf(i.sport) !== -1 })
      .toArray()
  }

现在在 html 中

<ion-item>
    <ion-label>Filter by Sport</ion-label>
    <ion-select multiple="true" (ionChange)="onChange($event)">
        <ion-option *ngFor="let item of (filterListBy$ | async)">{{item}}</ion-option>
    </ion-select>
</ion-item>

【讨论】:

  • Aaron,这正是我正在寻找的行为,非常感谢。现在,我正在尝试将您的想法添加到我的应用程序中,但我收到一条错误消息,提示“无法观察到它的不足”。谷歌搜索不是很清楚,因为我看到了这个错误的许多不同情况。这可能与从我设置的后端中提取的列表有关?我在那里将 .ts 代码添加到我的帖子中,因此您可以通过从我的提供程序中提取信息来查看我最初是如何填充屏幕的(代码已注释,因为我正在尝试使用您的想法)。再次感谢亚伦
  • Aaron,我收回了这一点,我能够让它发挥作用,并将解决方案添加到我的帖子中。再次感谢您的帮助!
  • 如果解决方案有效,您应该将其标记为正确...很高兴我能提供帮助
  • 嗨亚伦,我注意到的是它并没有很好地持久化,例如,无论我更改标签,它都会返回显示整个列表,即使离子选择仍在检查。你对此有什么建议吗?我编辑了这篇文章,说明了到目前为止我是如何适应你的建议的。再次感谢!
  • 将代码从 ngOnInit 移动到另一个生命周期方法,该方法在页面呈现时调用
猜你喜欢
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 2015-10-22
  • 2013-01-31
  • 1970-01-01
相关资源
最近更新 更多