2013-10-11 37 views
5

这看起来很简单,我找不到答案。angularjs - 由多个模型筛选

比方说,我有一组数据,设置了如下所示:

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

现在,我想基于像这样的文本输入来过滤数据:

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

这工作正常,但它会根据朋友对象的每个属性(姓名,年龄,地点和街道)过滤输入文本。我希望能够仅根据名称和位置进行过滤(忽略年龄和街道)。这可能没有自定义过滤器?

回答

7

是的,这可以通过简单地传递一个谓词的过滤器,而不是一个字符串:

<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

谢谢,很好地工作。值得一提的是,我需要将文本转换为小写,并添加if(!$ scope.searchText)返回1;让它起作用。 – user2424495

+0

只是要注意 - 添加'if(!$ scope.searchText)返回1;'如果没有搜索文本输入,将导致它返回所有结果(不过滤)。如果您需要这种方法,那么这种方法的优势在于我列出的方法。 – KayakDave

1

或者您可以使用:

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

+0

这可能是你想要的,除了searchText需要引号。过滤器:{name:'searchText'}。这将告诉角度它是一个字符串而不是一个表达式。 – Adam

+1

其实@Adam检查这个小提琴:http://jsfiddle.net/Dwesk/1/它不适用于引号,没有。 – KayakDave

+0

你是对的,我们想在这种情况下表达一个意思,我误解了最初的问题和答案。 – Adam

2

下面是我们如何用做定制过滤器。

DEMOhttp://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

这工作太棒了! – szymon

-1

你可以把几个过滤器就像....

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