Angular and Ionic newbie, working on an Ionic app and displaying assets received as json via an angular data service. I would like to filter my "asset" data via a second listing (of "groups") where each group object includes the IDs for those assets that are members of that group. This will be a second filter filtering the data presented in the view, and this group filter will present only those assets that are members of the selected group.
Here is the basic structure for my two objects (simplified):
"assets": [
{"id": 1, "deviceName": "vehicle 1", "vRoadSpeed": 40},
{"id": 2, "deviceName": "vehicle 2", "vRoadSpeed": 50},
{"id": 3, "deviceName": "vehicle 3", "vRoadSpeed": 40}
]
and
"groups":[
{"id": 1, "name": "downtown", "members": [{"id": 1},{"id": 2}]},
{"id": 2, "name": "west", "members": [{"id": 1},{"id": 3}]},
{"id": 3, "name": "east", "members": [{"id": 1}]}
]
I would like to filter values in the first object ("assets") by its id
which corresponds to the the nested "members" id
in the second object. e.g.: if I select group id 3 ("east"), the "assets" array would return only asset 1, "vehicle 1"
Here's the code I have so far:
controller:
.controller("AssetListCtrl",['$scope', 'dataService', function($scope, dataService){
var assets = [];
var groups = [];
dataService.getAssets().then(function(assets){
$scope.assets = assets;
})
dataService.getGroups().then(function(groups){
$scope.groups = groups;
}),
$scope.filterFunction = function(element){
return element.name.match(/^Ma/) ? true : false;
};
}])
Directive:
.directive('testDirective',function(){
return{
controller: 'AssetListCtrl',
replace: true,
link: function(scope, element, attrs){
scope.selectedGroups = {};
scope.noGroupsSelected = true;
scope.filterByGroup = function(){
angular.forEach(scope.assets, function(asset){
var match = false;
angular.forEach(asset.groups, function(g) {
if (scope.selectedGroups[g.id]){
match = true;
}
});
asset.matchesGroup = match;
});
scope.noGroupsSelected = true
angular.forEach(Object.keys(scope.selectedGroups), function(k) {
if (scope.selectedGroups[k]) {
scope.noGroupsSelected = false;
}
});
}
}
}
})
Data Service:
.factory('dataService', function($http){
var assets = {};
var groups = {};
//calling JSON array
return {
getAssets: function(){
return $http.get('../lib/data/sampleData.json').then(function(response){
assets = response.data.assets; //populate variable 'assets'
return response.data.assets;
});
},
getAsset: function(index){
return assets[index];
},
getGroups: function(){
return $http.get('../lib/data/sampleData.json').then(function(response){
groups = response.data.groups; //populate variable 'groups'
return response.data.groups;
});
}
}
})
html:
<div test-directive>
Groups:
<div ng-repeat = "group in groups">
<label>
<input type="checkbox" ng-model="selectedGroups[group.id]" name="groups_group" ng-change="filterByGroup()">{{group.name}}
</label>
</div>
<br>Assets
<div class="content wrapper" infinite-scroll="addMoreItems()" infinite-scroll-distance="2">
<ion-item ng-repeat="asset in filteredAssets = (assets | filter: query) | limitTo: config.itemsDisplayedInList track by asset.id" ng-if="asset.matchesGroup || noGroupsSelected" ui-sref='app.AssetListDetail({index: $index})'>
<div class = "row">
{{asset.deviceName}}
</div>
</ion-item>
</div>
</div>
(Note I'm currently trying to implement the infinite scroll as recommended in this posting: http://www.williambrownstreet.net/blog/2013/07/angularjs-my-solution-to-the-ng-repeat-performance-problem/. Per How to improve performance of ngRepeat over a huge dataset (angular.js)?, Ionic's 'collectionRepeat' directive is also supposed to be very performant, but it wouldn't work with 'ng-show' and 'ng-if' so have not included it here)
What I would like to do is similar to what is posed in this post: Angular JS - Creating a filter to compare 2 arrays. I have implemented the code as per the accepted answer, and it works, but I also need to implement a second filter on the data (essentially a general search field).
It looks like it's not good practice to use both a filter and ng-show
(Get the length of list shown by ng-Show've substituted ng-if
). So how do I do that?
All suggestions and comments on data structure and code welcome.