Reputation: 193
I have a collection of items which I'm using with ng-repeat and filtering.
Each item has a unique Id, and is stored in an array:
[ {id: 387, name: "hello"}, {id: 2878, name: "world"}, ...]
But now I need to reference these objects by their unique id instead of array index (as well as use ng-repeat with filters).
So I tried using a sparse array:
array[387] = {name: "hello"}; array[2878] = {name: "world"}...
But ng-repeat craps itself because it sees 'duplicate' undefined keys. (I also tried using 'track by' but ng-repeat still didn't like it).
I can't use an object with ng-repeat because filters don't work.
Soooo, how can I both use ng-repeat with filters, and be able to reference the items by id? The only option I can think of is to have a second data structure to map id's to indexes.
Thanks for your help!
Chris.
Upvotes: 0
Views: 884
Reputation: 907
Try this:
'track by $index'
ng-repeat="name in Lists track by $index"
Upvotes: 1
Reputation: 3410
I can see your ids are integer. angular filters not working because angular use string comparison for number.
Go to the angular.js search a function name filterFilter
. line 13991 for v1.2.10. Then you can use objects in your ng-repeat.
function filterFilter() {
...
var search = function(obj, text){
if (typeof text == 'string' && text.charAt(0) === '!') {
return !search(obj, text.substr(1));
}
switch (typeof obj) {
case "boolean":
case "number": // <-- here
// add return obj === text;
case "string":
return comparator(obj, text);
case "object":
switch (typeof text) {
case "object":
return comparator(obj, text);
default:
for ( var objKey in obj) {
if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
return true;
}
}
break;
}
return false;
case "array":
for ( var i = 0; i < obj.length; i++) {
if (search(obj[i], text)) {
return true;
}
}
return false;
default:
return false;
}
};
Upvotes: 0
Reputation: 33179
When I need to achieve this sort of thing, I do some quick preprocessing of the data grabbed, and create the necessary lookup. For example:
var data = [
{ id: 55, name: 'some name' },
{ id: 65, name: 'another name' }
];
// create a lookup
var lookup = {};
angular.forEach(data, function(item){
lookup[data.id] = item;
});
You could manipulate the data any way you want here, but by referencing the actual array items, you can bind either the data or lookup (or both) to $scope
, and any changes will be exhibited on both structures. Bear in mind this won't happen if you add/remove items from the array, as you need to manage the addition and removal of items from the lookup.
Upvotes: 0