疑問に思っていること: AngularJS では、'and' の代わりに 'or' 関係を持つようにフィルタリングするネイティブな方法はありますか?
例えば:
<tr ng-repeat="account in accounts | filter1 *OR* filter2 *OR* filter3" >
そのため、いずれかのフィルタが一致すると、そのオブジェクトが返されます。現時点では、表示されるためには 3 つすべてに合格する必要があります。
どうもありがとう、Y
疑問に思っていること: AngularJS では、'and' の代わりに 'or' 関係を持つようにフィルタリングするネイティブな方法はありますか?
例えば:
<tr ng-repeat="account in accounts | filter1 *OR* filter2 *OR* filter3" >
そのため、いずれかのフィルタが一致すると、そのオブジェクトが返されます。現時点では、表示されるためには 3 つすべてに合格する必要があります。
どうもありがとう、Y
カスタムフィルターを作成できます。他のフィルターの名前を受け入れ、それらのそれぞれをチェックして、配列内の各項目がaccounts
いずれかのフィルターに対して有効な一致であるかどうかを確認できます。次の例は一種のアイデアを示していますが、実際にコードを実行して動作するかどうかを確認していないため、タイプミスがあればご容赦ください。
app.filter('anyOf', function($filter) {
return function(){
var array = arguments[0];
var result = [];
angular.forEach(array, function(item){
for(var i=1; i<arguments.length; i++){
var filter = $filter(arguments[i]);
if(filter([item]).length){
result.push(item);
break;
}
}
});
return result;
}
});
そして、次のように使用します。
<tr ng-repeat="account in accounts | anyOf:'filter1':'filter2':'filter3'" >
入力配列内のすべてのアイテムを取得し、フィルターのいずれかと照合するため、あまり効率的ではありませんが、機能するはずだと思います。ただし、アカウントの配列が非常に長くない場合は、これでうまくいく可能性があります。
$filter を使用して独自のコードでフィルターを呼び出すことができるため、フィルター名を引数として新しいフィルターに渡して、結果をマージすることができます(JSFIDDLE)。
app.filter('merge', function($filter) {
return function(input, extra) {
var result = [];
for (var i = 1; i < arguments.length; i++) {
angular.forEach($filter(arguments[i])(input), function(item) {
if (result.indexOf(item) < 0) {
result.push(item);
}
});
}
return result;
};
});
そして、次のように引数をフィルターに渡すことができます:
<ul>
<li ng-repeat="item in items|merge:'color':'rating'">
{{item.rating}}: {{item.color}}
</li>
</ul>
マージするフィルターに引数を渡したい場合は、マージ フィルターでそれらを自分で解析できます。
<h3>Merge brown and rating >= 5</h3>
<ul>
<li ng-repeat="item in items|mergeWithArgs:['color','brown']:['rating',5]">
{{item.rating}}: {{item.color}}
</li>
</ul>
コード:
app.filter('mergeWithArgs', function($filter) {
return function(input) {
console.dir(arguments);
var result = [];
for (var i = 1; i < arguments.length; i++) {
var params = arguments[i];
var filter = $filter(params[0]);
// remove filter name, prepend input
params.splice(0, 1, input);
angular.forEach(filter.apply(this, params), function(item) {
if (result.indexOf(item) < 0) {
result.push(item);
}
});
}
return result;
};
});