AngularJS:如何防止递归模板永远循环

时间:2015-10-22 08:26:35

标签: javascript angularjs

我编写了一组代码,当绑定到一个对象时,它将显示该对象中每个属性的键和值。

<script type="text/ng-template" id="object-displayer">
   <div ng-if="recurrable(value)">
     <span class="recurrable">
       <span class="key">{{key}}</span>
       (<span class="type" ng-bind="type(value)"></span>)
     </span>
     <ul class="indent">
       <li ng-repeat="(key, value) in value track by $index" ng-include="'object-displayer'"></li>
     </ul>
   </div>

   <div ng-if="!recurrable(value)">
     <span class="primitive">
       <span class="key">{{key}}</span> (<span class="type" ng-bind="type(value)"></span>): <span class="value">{{value}}</span>
     </span>
   </div>
</script>

在控制器内:

$scope.recurrable = function (value) {
  return typeof value === 'object';
}

$scope.type = function (value) {
  return typeof value;
}

jsbin:(https://jsbin.com/xusiteluwi/1/edit?html,js,output

当嵌套对象创建简单的树结构时,这非常有用。但是在创建循环时会抛出异常:如果您的某个属性引用了上游的任何对象,它将一直显示,直到达到摘要限制(通常为10)。

现在这是我的问题。在角度控制器/模板到ng中是否有某种方法 - 如果一个对象是否已经被显示,从而捕获任何循环并仅显示一次迭代?

如果你能想出一个全局应用于图表的解决方案,或者只能跟踪当前分支的解决方案,那么

奖励积分。

2 个答案:

答案 0 :(得分:0)

从空的visitedReferences开始。

每次遇到任何引用(对象)时,检查它是否在visitedReferences中,如果是,请不要遵循此引用,否则将其添加到visitedReferences。

答案 1 :(得分:0)

希望帮助你!

&#13;
&#13;
angular
  .module('test', [])
  .controller('RecursiveCtrl', function($scope) {
    var vm = $scope;
    
    vm.data = {
      a: 'Hello',
      b: {
        c: 'World'
      }
    };
  
    vm.isRecursive = function(value) {
      return angular.isObject.call(this, value);
    };
  })
;
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<article data-ng-app="test">


  <div data-ng-controller="RecursiveCtrl">
  
    <script type="text/ng-template" id="tpl-recursive">

      <div ng-switch="isRecursive(value)">
      
      <div ng-switch-when="false" >
        <strong ng-bind="prop"></strong>: <span ng-bind="value"></span>
      </div>
  
        <div ng-switch-when="true">
           <ol>
            <li ng-repeat="(prop, value) in value" ng-include="'tpl-recursive'">
            </li>  
          </ol>
        </div>      
      </div>


    </script>
  


    <ol>
      <li ng-repeat="(prop, value) in data" ng-include="'tpl-recursive'"></li>
    </ol>
  </div>
  
</article>
&#13;
&#13;
&#13;