Suppose I have the following data:
sampleData = [{'artist': 'John', 'id': 1}, {'artist': 'John', 'id': 2},
{'artist': 'Tim', 'id': 3}, {'artist': 'Jimmy', 'id': 4}, {'venue': 'Rock club', 'id':1}, {'venue': 'Rock club', 'id': 2}, {'venue': 'Tonys', 'id': 3}]
This data can be found in my controller and will be non-changing. What I want to do is construct two nested lists within a main <ul>
.
Given I have the following input where where a user types 'J' or 'j':
<input ng-model="query" type="text" placeholder="Filter by">
This is what I would like to have rendered using ng-repeat(unless I don't have to use ng-repeat):
<ul>
<h1>artist</h1>
<li>
<ul>
<li>John (There are two 2 Johns)</li>
<li>Jimmy</li>
</ul>
</li>
<li>
<ul>
<h1>Venue</h1>
<li>Jock Club (There are two 2 Jock Club)</li>
</ul>
</li>
</ul>
Initially, I attempted to write a customer filter that took in the results from the filtered list and manipulated the data. Angular wasn't happy with my filter because I was modifying the original data too much and so I was receiving an infinite digest loop. So now I am back at square one trying to decide if this is best done with a directive or filter. I suspect that I need to restructure my data in my controller or in a directive to get my intended outcome. Again, my intended outcome would be a filtered with artist and venue sublists of sampleData
that is based on what a user is typing. Updating in a real time is ideal.
If you don't want to restructure your data, it can be achieved by having functions in your controller that use a filter to get only the items you want for each ng-repeat:
In controller:
var sampleData = [...];
$scope.query = '';
$scope.getArtists = function () {
return $filter('filter')(sampleData, function (item) {
return item.hasOwnProperty('artist') && item.artist.indexOf($scope.query) > -1;
});
};
$scope.getVenues = function () {
return $filter('filter')(sampleData, function (item) {
return item.hasOwnProperty('venue') && item.venue.indexOf($scope.query) > -1;
});
};
HTML:
<input ng-model="query" type="text" placeholder="Filter by">
<ul>
<li ng-repeat="artist in getArtists()"></li>
</ul>
<ul>
<li ng-repeat="venue in getVenues()"></li>
</ul>
However, it is probably better to restructure your data up front, so that you are able to iterate through venues and artists using a single function more efficiently:
In controller:
var sampleData = [...];
$scope.query = '';
$scope.artists = [];
$scope.venues = [];
angular.forEach(sampleData, function (item) {
if (item.hasOwnProperty('artist') {
$scope.artists.push({
id: item.id,
name: item.artist
});
});
else if (item.hasOwnProperty('venue') {
$scope.venues.push({
id: item.id,
name: item.venue
});
});
});
$scope.getMatching = function (items, query) {
return $filter('filter')(items, function (item) {
return (item.name.indexOf(query) > -1);
});
};
HTML:
<input ng-model="query" type="text" placeholder="Filter by">
<ul>
<li ng-repeat="artist in getMatching(artists, query)"></li>
</ul>
<ul>
<li ng-repeat="venue in getMatching(venues, query)"></li>
</ul>
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments