2017-10-17 50 views
0

我有一个ngFor迭代对象数组。我在UI中的表格中显示这些信息,并且它一切正常。Angular - Filter ngFor对象的数组数组

我想实现一个小过滤器框,所以我可以根据输入框中的内容缩小结果范围。

我为此使用了一个pipe并且它使用了一组数据,但我不确定如何在没有指定特定键的情况下搜索对象。我希望能够输入search term,并且如果它是任何一个对象中的值,请对其进行过滤。

管:

@Pipe({ name: 'filter' }) 
export class FilterPipe implements PipeTransform { 
    public transform(values: any[], filter: string): any[] { 
    if (!values || !values.length) return []; 
    if (!filter) return values; 

    return values.filter(v => v.indexOf(filter) >= 0); 
    } 
} 

组件:

dataObj = [ 
    { 
    name: 'Bob', 
    age: 21, 
    location: 'USA' 
    }, 
    { 
    name: 'Sally', 
    age: 25, 
    location: 'UK' 
    }] 

    filterString = ''; 

HTML:

<div> 
    <h2>Hello {{name}}</h2> 
    <input [(ngModel)]="filterString" /> 
    <div *ngFor="let d of (dataObj | filter: filterString)"> 
    {{ d.name }} - {{ d.age }} - {{ d.location }} 
    </div> 
</div> 

期望的结果:

如果我输入了21SallyUS,我期望看到结果。我试图避免将一个密钥硬编码到我搜索的管道中,因为我希望该对象内的所有值都是可搜索的。

这里是一个plnkr例如:https://plnkr.co/edit/ubLyB152hgrPJSVp8xSB?p=preview

+0

我有一个博客帖子这个位置:https://blogs.msmvps.com/ deborahk/filtering-in-angular/ – DeborahK

回答

2

您可以通过Object.keys(o)通过所有对象键循环,并检查是否有一些比赛中至少一个对象字段。

您还需要处理v[k]的类型,因为indexOf仅适用于字符串(和数组),不适用于数字。

像这样的东西应该做的工作:

public transform(values: any[], filter: string): any[] { 
    if (!values || !values.length) return []; 
    if (!filter) return values; 

    return values.filter(v => { 
     let match = false; 

     Object.keys(v).forEach(k => { 
      if (typeof v[k] === 'string') { 
       match = match || v[k].indexOf(filter) >= 0; 
      } else { 
       match = match || v[k] == filter; // == intentinally 
      } 
     }); 

     return match; 
    }); 
} 

这是您plunker与此修复程序:https://plnkr.co/edit/JoJ8M6YoID2yU6ASGEXf?p=preview

+0

这似乎很好地工作,直到它缩小到一个结果,然后它不显示任何内容。例如,如果我输入“U”,它会找到两个,但如果我输入“USA”,只有一个结果,它什么也没有显示。 – SBB

+0

我认为这是因为在数字上使用了'indexOf',请参阅我编辑的答案。我还加入了似乎可以正常工作的活塞。 –

+0

谢谢,这看起来不错。由于它是区分大小写的,所以它丢掉了我的东西。我会为此抛出一些东西。 – SBB