【问题标题】:How to create a custom pipe for filtering with multiple checkboxes? Angular 4如何创建自定义管道以使用多个复选框进行过滤?角 4
【发布时间】:2017-06-27 15:56:58
【问题描述】:

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

<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)">

【问题讨论】:

    标签: angular pipe ionic3


    【解决方案1】:

    编辑:

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

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

    (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

    【讨论】:

    • 完美运行!谢谢你。我确实遗漏了一个您可以提供帮助的细节?我有2个部分。今天和当前。这会一次过滤所有这些,并忽略我的日期过滤。反正有没有让我的日期过滤?我在上面编辑过。
    • 很高兴听到它奏效了。至于你的后续行动......我认为我明白你的意思。快速解决方案是首先过滤日期,然后使用我提供的上述代码 refilter。太丑了。但是我很难将这些代码拼凑在一起,因为我看不到整个画面,只有几个代码 sn-ps,甚至不确定您的应用程序中到底发生了什么。
    • 我很抱歉。我已经编辑了我的代码以使其更加清晰。
    • 没问题。感谢您的所有帮助:)!
    • Cody,我更新了答案并将代码转换为管道,而不是在组件中使用该方法 :) 希望现在对你有用 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 2016-10-26
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    相关资源
    最近更新 更多