Here's an alternate version rendering each select individually. It's using a custom groupBy
filter (using underscore):
app.filter('groupBy', ['$parse', function ($parse) {
return function groupByFilter(input, groupByExpr) {
return _.groupBy(input, $parse(groupByExpr));
};
}]);
with:
<div ng-repeat="(categoryTypeName, categories) in groupedCategories track by categoryTypeName">
<label>{{categoryTypeName}}</label>
<select
ng-model="selected[categoryTypeName]"
ng-options="c as c.name for c in categories track by c.id"
multiple
></select>
</div>
Unfortunately the filter has to be applied when the the data changes,
$scope.$watchCollection('categories', function (categories) {
$scope.groupedCategories = groupByFilter(categories, 'categoryType.name');
});
because if used with ng-repeat
directly angular will complain about an Infinite $digest Loop.
Demo: http://plnkr.co/edit/ipfVfH3pbLoYk1u4n3la?p=preview
On the other hand, given your requirements, it would be a lot simpler if your json would already be structured the way you need it (category types with a list of child-categories, not the other way around).
original answer:
I can't really picture your final layout, but a simple starting point could be the group by
feature of ng-options
.
E.g.:
<select
ng-model="selected"
ng-options="c as c.name group by c.categoryType.name for c in categories track by c.id"
></select>