【问题标题】:Angular 6 checkbox filter overrides previous checkboxAngular 6 复选框过滤器覆盖以前的复选框
【发布时间】:2019-04-05 11:06:42
【问题描述】:

我正在尝试使用复选框构建过滤器。下面是我的代码的 sn-p:

filter.pipe.ts

import { Pipe, PipeTransform, Injectable } from '@angular/core';

@Pipe({
  name: 'filter2'
})
@Injectable()
export class FilterPipe implements PipeTransform {
  transform(items: any[], field: string, value: string): any[] {
    if (!items) {
      return [];
    }
    if (!field || !value) {
      return items;
    }

    var newArray = [];
    items.filter(singleItem => {
      if (singleItem != null && singleItem[field] != null && singleItem[field] != undefined && singleItem[field].includes(value)) {
        newArray.push(singleItem);
      }
    })
    return newArray;
  }
}

app.html

<ng-container *ngFor="let group of groups;  let i=index">
     <label class="btn btn-filter" id="bttns">
            <input type="checkbox" name="customersGroupFilter" autoComplete="off" [value]="group" (change)="changeGroup($event)">
                      {{ group }}
     </label>&nbsp;
 </ng-container>

.....

 <tr *ngFor="let user of usersList | filter2: 'group' : groupValue">

.....

app.ts

groups = ['a', 'b', c']
usersList = [{'name': 'john', 'group': 'a'}, {'name': 'mike', 'group': 'a'}, {'name': 'doe', 'group': 'b'}, {'name': 'tim', 'group': 'c'}]
groupValue

changeGroup(event) {
    this.groupValue = event.target.value
}

这很好用,但如果我想进行多次检查,新的复选框值将始终覆盖我以前的值,因此无法进行多次检查。

例如:

如果我检查组 'a' => 它会返回给我 john, mike

如果我检查 'a' 和 'b' => 它只会返回我的 doe

如何修改我的代码以达到我想要的效果?感谢您的宝贵时间!

【问题讨论】:

    标签: javascript html angular filter


    【解决方案1】:

    你做错了一些事情。首先,you shouldn't use a filtering pipe。该过滤器每秒会被调用多次,并且可能会减慢您的应用程序的速度。而是在单击复选框时运行过滤器功能。

    changeGroup(event) {
        // filter function here
    }
    

    让我眼前一亮的第二件事是过滤器的误用。 Array.filter() 为您过滤数组 - if 语句必须是回调的返回值

    this.newArray =  items.filter(singleItem => 
      singleItem != null && singleItem[field] != null && singleItem[field] != undefined && singleItem[field].includes(value)
    )
    

    然后你可以使用 newArray...

    所以你以前过滤的用户列表变成了

    <tr *ngFor="let user of newArray">
    

    【讨论】:

    • 那么在我的changeGroup(event) 中我应该调用哪个函数,因为我不太明白你在说什么,抱歉。
    • 基本上,您可以在 changeGroup 中调用更正后的 transform 方法并将其结果应用到组件中的 newArray 上。您标记为正确的答案不是您应该这样做的方式!!! @Tenzolinho
    • 问题是我的管道不支持多值;正如你所说,它仍然无法正常工作。
    【解决方案2】:

    如果您真的想使用 Angular Pipe,这里是一个工作示例 https://stackblitz.com/edit/angular-qw7kkf

    1. 您需要更改 Pipe 中的转换函数以支持多个组值

      transform(items: any[], field: string, value: string[]): any[] {
      if (!items) {
        return [];
      }
      if (!field || !value || value.length <= 0) {
        return items;
      }
      return items.filter(singleItem => {
        return (singleItem != null && singleItem[field] != null && singleItem[field] != undefined && value.indexOf(singleItem[field]) >= 0);
      });
      

      }

    看到value的类型从string变成了string[],还有Array.filter 函数

    2.将groupValue的类型也从string改为string[]。这是你的新 changeGroup() 函数

    changeGroup(event) {
      const group = event.target.value;
      const index = this.groupValue.indexOf(group);
      if ( index < 0) {
        this.groupValue.push(group);
      } else {
        this.groupValue.splice(index, 1);  
      }
      const newGroupValue = [];
      newGroupValue.push.apply(newGroupValue, this.groupValue);
      this.groupValue = newGroupValue;
    }
    

    现在检查一个组也意味着在groupValue中触发它。请注意,我每次都必须为 this.groupValue 分配一个新数组是多么麻烦,因为如果你不这样做,filter2 管道将无法检测到更改“insidethis.groupValue 数组。 这也是我不推荐你使用 Pipe 的原因,Angular Pipe 有点过了。

    【讨论】:

    • 我不能有管道,这只是我认为我可以处理这种情况的一个版本;欢迎任何其他解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 2018-01-27
    • 2018-04-20
    • 1970-01-01
    • 2019-09-13
    相关资源
    最近更新 更多