私は次のようなJSONオブジェクトを持っています
[{
"id": 1,
"firstName": "Jennifer",
"middleName": null,
"lastName": "Aniston",
"address": "New York City",
}, {
"id": 2,
"firstName": "Angelina",
"middleName": null,
"lastName": "Jolie",
"address": "Beverley Hills",
}, {
"id": 3,
"firstName": "Emma",
"middleName": null,
"lastName": "Watson",
"address": "London",
}]
Ng-repeatを使用して、このデータをビューに入力しています。
<td ng-repeat="row in list | filter:filterBeauties">
{{row.firstName}} {{row.lastName}}
</td>
これで、これらの名前をフィルタリングするために使用したい入力ボックスができました。同じ入力ボックスを使用してfirstNameをフィルタリングし、次にlastNameをフィルタリングし、他には何もフィルタリングしません(アドレスなど)。
<input type="text" placeholder="Filter" ng-model="filterBeauties.firstName">
どうすればそれを達成できますか?
さて、これは私がそれを解決するためにしたことです。
Jsonオブジェクトに新しいアイテムを追加し( angular.forEach 関数を使用)、それによってフィルタリングしました。
$scope.list = beauties.query(function(response) {
angular.forEach(response, function(value, key) {
var fullName = value.firstName + ' ' + value.lastName;
$scope.list[key].fullName = fullName;
});
});
入力ボックスコード:
<input type="text" placeholder="Filter" ng-model="filterBeauties.fullName">
ng-repeat
<td ng-repeat="row in list | filter:filterBeauties">
{{row.firstName}} {{row.lastName}}
</td>
これを試してください フィドル 。
基本的に、表示されているデータ構造内でフィルタリングするためのサブ構造を作成し、そのプロパティでのみフィルタリングします(例: 'filterTerms'):
HTML:
<div ng-controller="MyCtrl">
<input type="text" ng-model="search.filterTerms">
<table border="1">
<tr ng-repeat="row in list | filter:search">
<td>{{row.firstName}} {{row.lastName}}</td>
</tr>
</table>
</div>
JavaScript:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.list = [{
"id": 1,
"address": "New York City",
"firstName": "Jennifer",
"middleName": null,
"lastName": "Aniston",
"filterTerms": {
"firstName": "Jennifer",
"middleName": null,
"lastName": "Aniston",
}
}, {
"id": 1,
"address": "New York City",
"firstName": "Jennifer",
"middleName": null,
"lastName": "Leela",
"filterTerms": {
"firstName": "Jennifer",
"middleName": null,
"lastName": "Leela",
}
}, {
"id": 2,
"address": "Beverley Hills",
"firstName": "Angelina",
"middleName": null,
"lastName": "Jolie",
"filterTerms": {
"firstName": "Angelina",
"middleName": null,
"lastName": "Jolie",
}
}, {
"id": 3,
"address": "London",
"firstName": "Emma",
"middleName": null,
"lastName": "Watson",
"filterTerms": {
"firstName": "Emma",
"middleName": null,
"lastName": "Watson",
}
}];
}
この場合、すべての名前を1つのフィールドに入力することで、これをさらに単純化できます(fiddle here を参照してください:
HTML:
<div ng-controller="MyCtrl">
<input type="text" ng-model="search.filterTerm" />
<table border="1">
<tr ng-repeat="row in list | filter:search">
<td>{{row.first}} {{row.last}} {{row.address}}</td>
</tr>
</table>
</div>
JavaScript:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.list = [{
"id": 0, "first": "Jenny", "last": "Sorenson", "address": "123 W. Wallnut St.",
"filterTerm": "Jenny Sorenson"
},{
"id": 0, "first": "Susan", "last": "Hinkle", "address": "456 W. Doorbell Dr.",
"filterTerm": "Susan Hinkle"
},{
"id": 0, "first": "Rachel", "last": "Karlyle", "address": "789 W. Sunset Blvd.",
"filterTerm": "Rachel Karlyle"
},{
"id": 0, "first": "Gwen", "last": "Lippi", "address": "0 W. Silly Cir.",
"filterTerm": "Gwen Lippi"
}]
}
ユーザーがこのフォームを持っていることを考えると:
{
"id": 2,
"firstName": "Angelina",
"middleName": null,
"lastName": "Jolie",
"address": "Beverley Hills"
}
ユーザーの1人をファーストネーム、ラストネーム、またはその両方で同時に検索する場合は、それらを連結する必要があります。
$scope.query = '';
$scope.search = function (user) {
var query = $scope.query.toLowerCase(),
fullname = user.firstName.toLowerCase() + ' ' + user.lastName.toLowerCase();
if (fullname.indexOf(query) != -1) {
return true;
}
return false;
};
この関数は、現在のユーザーがクエリを満たしている場合はtrue
を返し、満たさない場合はfalse
を返します。関数内では、クエリを小文字にすることをお勧めします。これにより、ユーザーが検索入力に入力する大文字を処理する必要がなくなります。
HTMLは次のとおりです。
<input type="text" placeholder="Search" ng-model="query">
<table>
<tr ng-repeat="user in users | filter:search">
<td>{{user.firstName}} {{user.lastName}}</td>
</tr>
</table>
この手法は、Angelina Jolie
、Angelina
、Jolie
、さらにはInA JOLIe
を検索しようとした場合にのみ機能します(結局のところ、そうではありません)。 Jolie Angelina
のような姓を最初に検索しようとすると、機能しません。関数に2番目のフルネーム(例:reverseFullname
)を作成し、最初にlastName、次にfirstNameを連結して、最初のフルネーム文字列と同じようにテストすることで、簡単に修正できます。
3番目の引数をフィルター関数に渡すことができます。
$filter('filter')(list, {'firstName':search});
私は以下のようなことをしたでしょう:
<input type="text" ng-model="search">
<table border="1">
<tr ng-repeat="row in list | filterBoth:search">
<td>{{row.firstName}} {{row.lastName}}</td>
</tr>
</table>
次に、カスタムフィルターを次のように記述します。
myApp.filter('filterBoth', function($filter) {
return function(list, search) {
if (!search) return list;
var arrSearch = search.split(' '),
lookup = '',
result = [];
arrSearch.forEach(function(item) {
lookup = $filter('filter')(list, {'firstName': item});console.log(lookup);
if (lookup.length > 0) result = result.concat(lookup);
});
return result;
};
});
デモ: http://jsfiddle.net/wAp4S/1/
唯一の問題は、_.uniq
underscore.jsメソッドを使用して簡単に修正できる2つの類似した配列を連結しているため、重複する行が発生することです。
複雑なフィルターを作成する代わりに、angular-filter
ライブラリを試してください。ここでは、searchField
フィルターが役立ちます。
https://github.com/a8m/angular-filter
[〜#〜]コントローラー[〜#〜]
$scope.users = [
{ first_name: 'Sharon', last_name: 'Melendez' },
{ first_name: 'Edmundo', last_name: 'Hepler' },
{ first_name: 'Marsha', last_name: 'Letourneau' }
];
[〜#〜] html [〜#〜]
<input ng-model="search" placeholder="search by full name"/>
<th ng-repeat="user in users | searchField: 'first_name': 'last_name' | filter: search">
{{ user.first_name }} {{ user.last_name }}
</th>
<!-- so now you can search by full name -->
幸運を。