2013-10-11 22 views
5

Điều này có vẻ như nó phải đơn giản, tôi không thể tìm thấy câu trả lời.angularjs - lọc theo nhiều mô hình

Hãy nói rằng tôi có một mảng dữ liệu, đặt ra như sau:

friends = [{name:'John', age:60, location:'Brighton', street:'Middle Street'}, 
{name:'Bob', age:5, location:'Brighton', street:'High Street'}]; 

Bây giờ, tôi muốn lọc dữ liệu dựa trên một đầu vào văn bản như vậy:

<input ng-model="searchText"> 
<ul> 
    <li ng-repeat="friend in friends | orderBy:'name' | filter:searchText"> 
    {{friend.name}} - {{friend.location}}</li> 
</ul> 

này hoạt động tốt nhưng nó lọc văn bản đầu vào dựa trên mọi thuộc tính của đối tượng bạn (tên, tuổi, vị trí và đường phố). Tôi muốn có thể lọc dựa trên tên và vị trí chỉ (bỏ qua tuổi và đường phố). Điều này có thể không có bộ lọc tùy chỉnh không?

Trả lời

7

Có, có thể bằng cách đơn giản thông qua một vị bộ lọc thay vì một chuỗi:

<li ng-repeat="friend in friends | orderBy:'name' | filter:friendContainsSearchText"> 

$scope.friendContainsSearchText = function(friend) { 
    return friend.name.indexOf($scope.searchText) >= 0 || friend.location.indexOf($scope.searchText) >= 0 
} 
+0

Cảm ơn, hoạt động tốt. Chỉ có điều đáng nói đến là tôi cần chuyển đổi văn bản thành chữ thường và thêm if (! $ Scope.searchText) trả về 1; để làm cho nó hoạt động. – user2424495

+0

Chỉ cần lưu ý thêm 'if (! $ Scope.searchText) trả về 1;' sẽ làm cho nó trả về tất cả các kết quả (không lọc) nếu không có văn bản tìm kiếm nào được nhập vào. Đây là một ưu điểm của phương pháp này trong cách tiếp cận mà tôi liệt kê nếu bạn cần. – KayakDave

1

Hoặc bạn có thể sử dụng:

<li ng-repeat="friend in friends | orderBy:'name' | filter:{ name :searchText}">

+0

Đây có thể là những gì bạn muốn, ngoại trừ searchText cần trích dẫn xung quanh nó. bộ lọc: {name: 'searchText'}. Điều này sẽ cho góc cạnh rằng nó là một chuỗi và không phải là một biểu thức. – Adam

+1

Trên thực tế @Adam xem câu đố này: http://jsfiddle.net/Dwesk/1/ Nó không hoạt động với dấu ngoặc kép, không có. – KayakDave

+0

Bạn hoàn toàn đúng, chúng tôi muốn có một biểu hiện trong trường hợp này, tôi hiểu lầm câu hỏi và câu trả lời ban đầu. – Adam

2

Sau đây là cách chúng tôi làm điều đó với một bộ lọc tùy chỉnh.

DEMO: http://plnkr.co/edit/q7tYjOvFjQHSR0QyGETj?p=preview)

[array] | search:query:columns:operator 

> query: this is the term you are looking for 
> columns: an array of the names of the properties you want to look for (if empty, will use the angular filter with query) 
> operator: a boolean to switch between OR (true) and AND (false, default) 

html

<ul> 
    <li ng-repeat="item in list | search:query:['name','location']:operator"> 
    <pre>{{item | json}}</pre> 
    </li> 
</ul> 

js

app.filter('search', function($filter) { 
    return function(input, term, fields, operator) { 
    if (!term) { 
     return input; 
    } 

    fields || (fields = []); 

    if (!fields.length) { 
     return $filter('filter')(input, term); 
    } 

    operator || (operator = false); // true=OR, false=AND 

    var filtered = [], valid; 

    angular.forEach(input, function(value, key) { 
     valid = !operator; 
     for(var i in fields) { 
     var index = value[fields[i]].toLowerCase().indexOf(term.toLowerCase()); 
     // OR : found any? valid 
     if (operator && index >= 0) { 
      valid = true; break; 
     } 
     // AND: not found once? invalid 
     else if (!operator && index < 0) { 
      valid = false; break; 
     } 
     } 
     if (valid) { 
     this.push(value); 
     } 
    }, filtered); 

    return filtered; 
    }; 
}); 
+0

Điều này đang hoạt động tuyệt vời! – szymon

-1

Bạn có thể đặt một số bộ lọc giống như ....

<div> 
    <input ng-model="Ctrl.firstName" /> 
    <input ng-model="Ctrl.age" /> 

    <li ng-repeat = "employee in Ctrl.employees | filter:{name:Ctrl.firstName} | filter:{age:Ctrl.age}">{{employee.firstName}}</li> 
</div> 
Các vấn đề liên quan