2015-10-22 48 views
0

我寫了一組代碼,當綁定到一個對象時,它將顯示該對象中每個屬性的鍵和值。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的某種方式 - 如果一個對象是否已經顯示,從而捕捉任何循環並只顯示一次迭代?

如果您可以想出一個將在圖表中全局應用的解決方案或僅跟蹤當前分支的解決方案,則可獲得獎勵分數。

回答

0

以空的visitedReferences開始。

每次遇到任何引用(對象)時,檢查它是否位於visitedReferences中,如果是,請不要跟隨此引用,否則將其添加到visitedReferences中。

+0

我怕我不明白。我在哪裏發起這個散列?如何在模板代碼中「遇到」時更新它? – user2849041

+0

嘿:)。首先,即使在你的試用期中,你也可以使用'ng-init'來更新它(即使這不是最佳實踐,但你可以)。如果你想讓我嘗試爲你編碼,請減少你的代碼js + html(我的意思是留下必要的東西),並將其工作代碼放在https://jsbin.com/上。一般來說,如果你把它放在jsbin/jsfiddle/plnkr或其他任何地方,你會從這裏的用戶得到更多的幫助: – Alexander

+0

https://jsbin.com/xusiteluwi/1/edit?html,js輸出 作爲沒有循環的例子和一個循環的例子: https://jsbin.com/wuqaxexina/1/edit?html,js,output – user2849041

0

希望能幫到你!

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); 
 
    }; 
 
    }) 
 
;
<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>