如何使用多个复选框创建自定义管道进行过滤? Angular 4

时间:2017-06-27 15:56:58

标签: angular pipe ionic3

我有一个状态列表,其值为: 调度,打开和关闭。当我点击复选框时,我想过滤结果

<ion-item *ngFor="let s of appointmentStatus" >
  <ion-checkbox [(ngModel)]="s.checked" (click)="updateFilter(s)"></ion-checkbox>
  <ion-label >{{ s.status }}</ion-label>
</ion-item>

<div *ngFor="let a of todaysAppointments>
//list of appointments goes here

我试图想出一种用管道来做这个的方法,但我没有找到一个很好的例子而且我很新。任何帮助将不胜感激。

if ((appDate.getDay() == currentDate.getDay()) && (appDate.getMonth() == currentDate.getMonth()) && (appDate.getFullYear() == currentDate.getFullYear()) && this.appointments[i].status != 'Pending') {
                this.todaysAppointments.push(this.appointments[i]);
            }
            if ((appDate.getDay() < currentDate.getDay()) && (appDate.getMonth() >= currentDate.getMonth()) && (appDate.getFullYear() >= currentDate.getFullYear()) && this.appointments[i].status != 'Pending') {
                this.upcomingAppointments.push(this.appointments[i]);
            }

因此,当您只有一个阵列时,您在下面所做的工作非常完美。在我的HTML上,我把它分为今天和即将到来的约会。所以我首先加载页面并显示相应部分中的所有约会。然后最重要的是我想通过复选框进行过滤。

<h2 style="background-color:#387ef5">Today's Appointments</h2>
<div *ngFor="let a of todaysAppointments | filter: searchTerm" (click)="openPage(a)">

<h2 style="background-color:#387ef5">Upcoming Appointments</h2>
<div *ngFor="let a of upcomingAppointments | filter: searchTerm" (click)="openPage(a)">

1 个答案:

答案 0 :(得分:2)

修改

由于我们正在处理两个数组,因此原始答案转换为管道而不是仅在组件文件中使用过滤器方法。

如果您想要添加或删除过滤器值,我们也可以保留updateFilter(s)方法,或者您可以在模板中为click事件执行此操作:

(click)="s.checked ? 
    filterArr.push(s.status) : filterArr.splice(filterArr.indexOf(s.status), 1)

我个人喜欢在组件中使用该逻辑来保持模板清洁,但这完全取决于您:)

在模板中,我们将该数组传递给管道:

<div *ngFor="let a of todaysAppointments | filterPipe: filterArr">

管道看起来像这样,其中values是要过滤的数组,args是选中复选框的数组。 (你想重新考虑命名)。我们必须使管道不纯净,以便在发生变化时将其触发。

@Pipe({name: 'filterPipe', pure: false})
export class MyPipe implements PipeTransform {
    transform(values: any, args?: any[]): any[] {
      return values = values.filter(a => {
        return args.length ? args.indexOf(a.status) != -1 : values;
      })      
    }
}

应该这样做!

<强> DEMO

原始答案:

这里根本不需要自定义管道。您可以在点击活动中使用Array.prototype.filter()

我们还需要检查是否选中了复选框,并根据检查的值进行过滤。我在这里将它们插入一个单独的数组filterArr

因此,在updateFilter(s)方法中,我们首先检查,将该过滤器值推送到数组,或将其删除。然后按值过滤,或者如果filterArr为空,则返回所有约会:

我们有一个单独的数组,用于存储名为allAppointments的所有约会,我们会从中将值过滤为todasyAppointments

updateFilter(appt) {
  if(appt.checked) {
    // checkbox is checked, push to filterArr
    this.filterArr.push(appt.status)
  }
  else {
    // unchecked box, let's remove it from array
    let index = this.filterArr.indexOf(appt.status)
    this.filterArr.splice(index, 1)
  }
  // filter by the values set in filterArr, or if empty, return all appointments
  this.todaysAppointments = this.allAppointments.filter(a => {
    return this.filterArr.length ? 
           this.filterArr.indexOf(a.status) != -1 : this.allAppointments;
  })
}

<强> DEMO