2017-10-17 93 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