I am a beginner in Angular and Ionic, currently developing an Ionic application that displays assets retrieved as JSON through an angular data service. My goal is to apply a second-level filter on my "asset" data using a separate list of "groups," where each group object contains the IDs of assets that belong to that specific group. This additional filter will refine the data shown in the view by only displaying assets that are part of the selected group.
Below is a simplified structure of my two objects:
"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}]}
]
My aim is to filter the values in the "assets" array based on its id
, which should match the nested "members" id
in the corresponding group from the second object. For example, selecting group id 3 ("east") would result in returning asset 1, "vehicle 1" from the "assets" array.
Here's what I have coded 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 = {};
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>
(Please note that I am exploring ways to implement infinite scroll based on recommendations found at: . As per advice found in How to improve performance of ngRepeat over a huge dataset (angular.js)?, although Ionic's 'collectionRepeat' directive is known for its efficiency, it may not be compatible with 'ng-show' and 'ng-if', hence omitted here)
The concept I am trying to achieve aligns with the approach discussed in this post: Angular JS - Creating a filter to compare 2 arrays. While I have successfully implemented the provided code snippet, I also need to incorporate a second filter on the data (like a general search field). However, combining a filter with ng-show
might not be recommended (Get the length of list shown by ng-Show-via substitution with ng-if
). How can I navigate around this limitation?
I welcome all suggestions and feedback regarding data structure and the coding approach.