如何给ng-repeat一个id?

时间:2016-01-04 14:42:04

标签: angularjs angularjs-ng-repeat

我有一个树形结构,需要为三个树中的每个级别设置不同的样式。因此我需要一些方法来跟踪项目所在的级别,所以我认为如果有某种方法可以动态地为ng-repeat(不是内部项目)设置唯一ID,我可以轻松地执行一些数学给出正确的内联样式。

现在我有一个使用三个文件的递归树结构;包装器,新级别和分支(与新级别相同)。 treeWrappertreeLevel是使用这些模板的指令。

我在ng-include文件中执行了tree-branch.html以使其递归。 ng-include内的第一个tree-level.html仅适用于" kickstart"递归。

所以我的问题是如何为树中的每个ng-repeat设置一个id?这甚至可能吗?

tree-wrapper.html

<div class="tree-wrapper">
    <tree-level ctrl="ctrl" tree="tree"></tree-level>
</div>

tree-level.html

<ul class="tree-list">
    <li class="tree-item" ng-repeat="branch in tree track by $index"
        ng-include="'/app/views/components/tree/tree-branch.html'"></li>
</ul>

tree-branch.html

<div ng-click="ctrl.toggleBranch(branch)" ng-bind="branch.name"></div>
<ul class="tree-list" ng-if="branch.branches">
    <li class="tree-item" style="padding-left: {{$index * 5}}" ng-repeat="branch in branch.branches" 
        ng-include="'/app/views/components/tree/tree-branch.html'"></li>
</ul>

1 个答案:

答案 0 :(得分:2)

这可以通过使用指令而不是包含来轻松完成。

树枝模板如下所示:

<ul class="branch-level-{{vm.level}}">
   <li ng-repeat="branch in vm.branch.branches">
       <tree-branch level="vm.level + 1" branch="branch"></tree-branch>
   </li>
</ul>

指令定义类似于

{
    scope : {
        level : '=',
        branch : '='
    }
}

tree-level.html中的kickstart可以简化:

<tree-branch level="0" branch="tree"></tree-branch>

请注意,使用指令的递归会炸毁编译器,您必须自己处理它。请参阅此帖子以了解如何操作:Recursion in Angular directives

&#13;
&#13;
/* 
 * An Angular service which helps with creating recursive directives.
 * @author Mark Lagendijk
 * @license MIT
 */
angular.module('RecursionHelper', []).factory('RecursionHelper', ['$compile',
  function($compile) {
    return {
      /**
       * Manually compiles the element, fixing the recursion loop.
       * @param element
       * @param [link] A post-link function, or an object with function(s) registered via pre and post properties.
       * @returns An object containing the linking functions.
       */
      compile: function(element, link) {
        // Normalize the link parameter
        if (angular.isFunction(link)) {
          link = {
            post: link
          };
        }

        // Break the recursion loop by removing the contents
        var contents = element.contents().remove();
        var compiledContents;
        return {
          pre: (link && link.pre) ? link.pre : null,
          /**
           * Compiles and re-adds the contents
           */
          post: function(scope, element) {
            // Compile the contents
            if (!compiledContents) {
              compiledContents = $compile(contents);
            }
            // Re-add the compiled contents to the element
            compiledContents(scope, function(clone) {
              element.append(clone);
            });

            // Call the post-linking function, if any
            if (link && link.post) {
              link.post.apply(null, arguments);
            }
          }
        };
      }
    };
  }
]);

angular.module('recursionDemo', ['RecursionHelper'])
  .controller("TreeController", function($scope) {
    $scope.treeFamily = {
      name: "Parent",
      children: [{
        name: "Child1",
        children: [{
          name: "Grandchild1",
          children: []
        }, {
          name: "Grandchild2",
          children: [{
            name: "GrandGrandchild1",
            children: []
          }]
        }, {
          name: "Grandchild3",
          children: []
        }]
      }, {
        name: "Child2",
        children: []
      }]
    };
  })
  .directive("tree", function(RecursionHelper) {
    return {
      restrict: "E",
      scope: {},
      bindToController: {
        family: '=',
        level: '='
      },
      controller: function() {},
      controllerAs: 'vm',
      template: '{{vm.family.name}} Level = {{vm.level}} ' +
        '<ul>' +
        '    <li ng-repeat="child in vm.family.children">' +
        '        <tree family="child" level="vm.level+1"></tree>' +
        '    </li>' +
        '</ul>',
      compile: function(element) {
        return RecursionHelper.compile(element, function(scope, iElement, iAttrs, controller, transcludeFn) {
          // Define your normal link function here.
          // Alternative: instead of passing a function,
          // you can also pass an object with 
          // a 'pre'- and 'post'-link function.
        });
      }
    };
  });
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="recursionDemo" ng-controller="TreeController">
  <tree family="treeFamily" level="0"></tree>
</div>
&#13;
&#13;
&#13;