2013-10-11 5 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)return 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> 
関連する問題