Angular-ui-select родительская и дочерняя группа

У меня есть массив, полный родительских объектов, и вложенный в каждый родительский объект, у меня есть массив с дочерними объектами. Не перестраивая свою модель, я изо всех сил пытаюсь найти лучший способ использовать angular-ui-select для достижения выпадающего списка выбора с включенной группировкой.

$scope.allCategories = [
        {
            "code": "AAAA",
            "name": "animals",
            "categories": [
                {
                    "code": "APET",
                    "name": "pets"
                },
                {
                    "code": "ASUP",
                    "name": "supplies"
                },
                {
                    "code": "AOTH",
                    "name": "other"
                }
            ]
        },
        {
            "code": "CCCC",
            "name": "community",
            "categories": [
                {
                    "code": "CCNW",
                    "name": "classes and workshops"
                },
                {
                    "code": "COMM",
                    "name": "events"
                },
                {
                    "code": "CGRP",
                    "name": "groups"
                }
            ]
        }
    ]

Вот то, что я построил до сих пор, но мне нужны многие функции angular-ui-select, не изобретая колесо.

<select class="form-control">
    <optgroup ng-repeat="category in allCategories" label="{{category.name}}">
        <option ng-repeat="childCategory in category.categories" value="{{childCategory.code}}">{{childCategory.name}}</option>
    </optgroup>
</select>

2 ответа

Я думаю, вам нужно сгладить вашу иерархию в массив.

Примерно так: http://plnkr.co/edit/ESHmxOqMuIvAYFdNYcV0

Вот функция выравнивания, которую я написал для вашего примера. Свойства могут быть легко адаптированы для других случаев использования:

function flattenCategories(categories, depth, parent){
  if(angular.isUndefined(depth)){ depth = 1; }
  var flat = [];
  angular.forEach(categories, function(category){
    flat.push({
                code: category.code,
                name: category.name,
                depth: depth,
                parent: parent
              });
    if(category.categories){
      var childCategories = flattenCategories(category.categories, depth+1, (angular.isDefined(parent)?parent+'.':'')+category.code);
      if(childCategories.length){
        flat.push.apply(flat, childCategories);
      }
    }
  });
  return flat;
}

$scope.flatCategories = flattenCategories( $scope.allCategories );

Использование свойства глубины в классе (т.е. class="depth-{{category.depth}}"), вы можете создавать отступы и стили заголовков групп. Вам нужно будет сгенерировать CSS для тех глубин, которые вам необходимо поддерживать.

Все зависит от того, что вы хотите, чтобы он был выбран.

Если вы хотите выбрать родителя, вы можете использовать только один выбор и отобразить вложенные данные, как во втором примере здесь: http://plnkr.co/edit/a3KlK8dKH3wwiiksDSn2?p=preview

<ui-select-choices repeat="person in people | propsFilter: {name: $select.search, age: $select.search}">
  <div ng-bind-html="person.name | highlight: $select.search"></div>
  <small>
    email: {{person.email}}
    age: <span ng-bind-html="''+person.age | highlight: $select.search"></span>
  </small>
</ui-select-choices>

если вы хотите выбрать ребенка, вы можете использовать два выбора в каскаде, как в этом примере (с обычными выборами): http://jsfiddle.net/annavester/Zd6uX/. Вы можете экстраполировать его для пользовательского интерфейса в соответствии с вашими потребностями

$scope.countries = ['usa', 'canada', 'mexico', 'france'];
$scope.$watch('country', function(newVal) {
    if (newVal) $scope.cities = ['Los Angeles', 'San Francisco'];
});
$scope.$watch('city', function(newVal) {
    if (newVal) $scope.suburbs = ['SOMA', 'Richmond', 'Sunset'];
});

Кстати, я не уверен, что вы можете использовать optgroup с ui-select

Другие вопросы по тегам