md-select with recursive options

时间:2017-10-02 12:01:49

标签: angularjs recursion angularjs-ng-repeat angularjs-material

我正在尝试使用子类别迭代一系列类别。

问题所在。我有这一系列的类别:

$scope.categories = [{
  "_id": 1,
  "name": "Cat 1",
  "categories": {
    "_id": 11,
    "name": "Cat 11",
    "categories": {
      "_id": 111,
      "name": "Cat 111",
      "categories": null
    }
  }
}, {
  "_id": 2,
  "name": "Cat 2",
  "categories": null
}, {
  "_id": 3,
  "name": "Cat 3",
  "categories": null
}];

如您所见,是一个带有子类别的对象数组,所以我知道我需要一个递归解决方案。

我需要将所有类别显示为md-select(它不是必要的组,但它会很棒)我正在尝试这个:

<md-input-container class="md-block">
  <label>Categories</label>
  <md-select ng-model="selectedCategory">
    <md-option ng-value="category._id" ng-repeat-start="category in categories">{{category.name}}</md-option>
    <span ng-repeat-end ng-include="'subcategories'" ng-if="category.categories"></span>
  </md-select>
</md-input-container>
<script type="text/ng-template" id="subcategories">
{{category.name}}
<md-option ng-value="category._id" ng-repeat-start="category in category.categories">{{category.name}}</md-option>
<span ng-repeat-end ng-include="'subcategories'" ng-if="category.categories"></span>

它部分有效,但不是预期的结果。

我想要什么?像这样的东西

enter image description here

我有什么? This code

告诉我是否需要更多细节。

由于

1 个答案:

答案 0 :(得分:1)

您可以简单地按照嵌套级别展平列表和样式元素。

angular
  .module('app', ['ngMaterial'])
  .controller('AppController', function($scope) {

    $scope.categories = [{
      "_id": 1,
      "name": "Cat 1",
      "categories": [{
        "_id": 11,
        "name": "Cat 11",
        "categories": [{
          "_id": 111,
          "name": "Cat 111",
          "categories": null
        }]
      }]
    }, {
      "_id": 2,
      "name": "Cat 2",
      "categories": null
    }, {
      "_id": 3,
      "name": "Cat 3",
      "categories": null
    }];

    $scope.flattenCategories = flatten($scope.categories, 0);

    function flatten(categories, level) {
      var flat = [];
      for (var i = 0, n = categories.length, category; category = categories[i]; i++) {
        flat.push({
          _id: category._id,
          name: category.name,
          level: level
        });
        if (category.categories) {
          flat = flat.concat(flatten(category.categories, level + 1));
        }
      }

      return flat;
    }

  });
.subcategory-0 .md-text {
  margin-left: 0;
}

.subcategory-1 .md-text {
  margin-left: 8px;
}

.subcategory-2 .md-text {
  margin-left: 16px;
}

.subcategory-3 .md-text {
  margin-left: 24px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular-messages.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.4/angular-material.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">

<div ng-app="app" ng-controller="AppController">
  <form name="myForm">
    <md-input-container class="md-block">
      <label>Categories</label>
      <md-select ng-model="selectedCategory" name="myCategory">
        <md-option ng-class="'subcategory-' + category.level" ng-value="category._id" ng-repeat="category in flattenCategories track by category._id">{{ category.name }}</md-option>
      </md-select>
      <!-- <pre ng-bind="flattenCategories | json"></pre> -->
    </md-input-container>
  </form>
</div>