2016-05-09 12 views
7

Mam obiekt JSON mający zagnieżdżone węzły, które mogą przejść na dowolnej liczbie poziomów. Potrzebuję wyświetlić zawartość węzła po kliknięciu jego węzła nadrzędnego. Byłoby to wyglądać mniej więcej tak enter image description hereJak wstawić ng-repeat wewnątrz ng-repeat dla n razy

 "node": [ 
    { 
     "id": "id of the concept model", 
     "name": "Curcumin", 
     "type": "conceptmodel", 
     "node": [ 
     { 
      "id": "group1", 
      "name": "Node 01", 
      "weight": "70", 
      "type": "text", 
      "node": [ 
      { 
       "id": "group11", 
       "name": "Node 02", 
       "weight": "70", 
       "type": "structure", 
       "node": [] 
      } 
      ] 
     } 
     ] 
    }, 
    { 
     "id": "id of the concept model", 
     "name": "Abuse Resistent Technology", 
     "type": "conceptmodel", 
     "node": [ 
     { 
      "id": "group1", 
      "name": "Category 01", 
      "weight": "70", 
      "type": "text", 
      "node": [] 
     } 
     ] 
    }, 
    { 
     "id": "id of the concept model", 
     "name": "PC in Aviation", 
     "type": "conceptmodel", 
     "node": [ 
     { 
      "id": "group1", 
      "name": "Industry", 
      "weight": "70", 
      "type": "text", 
      "node": [ 
      { 
      "id": "group1", 
      "name": "Node 01", 
      "weight": "70", 
      "type": "text", 
      "node": [] 
      } 
      ] 
     } 
     ] 
    } 
    ] 

ja zrobiłem coś takiego na dwóch poziomach:

<div class="conceptModels"> 
    <!--tree starts--> 
    <ul class="tree"> 
     <span class="treeBlk"> 
     <li ng-repeat="conceptModel in conceptModels.node" > 
      <span ng-click="levelOne=true" class="textSpan show top">{{conceptModel.name}}<span class="arrclose"></span></span> 
      <ul ng-show="levelOne"> 
       <li ng-repeat="node1 in conceptModel.node"> 
        <span ng-click="levelTwo=true" class="textSpan">{{node1.name}}<span class="arrclose"></span></span> 
        <ul ng-show="levelTwo"> 
        <li ng-repeat="node2 in node1.node"> 
         <span class="textSpan">{{node2.name}}<span class="arrclose"></span> </span> 
        </li> 
        </ul> 
       </li> 
      </ul> 
     </li> 
     </span> 
    </ul> 
</div> 

Czy istnieje sposób uogólnić to rozwiązanie do dowolnej liczby poziomie ??

+0

Możliwe duplikat [pomocą ng powtarzania wewnątrz innego ng powtarzania] (http://stackoverflow.com/questions/31484686/using-ng-repeat -inside-another-ng-repeat) –

Odpowiedz

13

Spróbuj to

var jimApp = angular.module("mainApp", []); 
 

 
jimApp.controller('mainCtrl', function($scope){ 
 
    $scope.nodes = [ 
 
     { 
 
      "id": "id of the concept model", 
 
      "name": "Curcumin", 
 
      "type": "conceptmodel", 
 
      "node": [ 
 
      { 
 
       "id": "group1", 
 
       "name": "Node 01", 
 
       "weight": "70", 
 
       "type": "text", 
 
       "node": [ 
 
       { 
 
        "id": "group11", 
 
        "name": "Node 02", 
 
        "weight": "70", 
 
        "type": "structure", 
 
        "node": [] 
 
       } 
 
       ] 
 
      } 
 
      ] 
 
     }, 
 
     { 
 
      "id": "id of the concept model", 
 
      "name": "Abuse Resistent Technology", 
 
      "type": "conceptmodel", 
 
      "node": [ 
 
      { 
 
       "id": "group1", 
 
       "name": "Category 01", 
 
       "weight": "70", 
 
       "type": "text", 
 
       "node": [] 
 
      } 
 
      ] 
 
     }, 
 
     { 
 
      "id": "id of the concept model", 
 
      "name": "PC in Aviation", 
 
      "type": "conceptmodel", 
 
      "node": [ 
 
      { 
 
       "id": "group1", 
 
       "name": "Industry", 
 
       "weight": "70", 
 
       "type": "text", 
 
       "node": [ 
 
       { 
 
       "id": "group1", 
 
       "name": "Node 01", 
 
       "weight": "70", 
 
       "type": "text", 
 
       "node": [] 
 
       } 
 
       ] 
 
      } 
 
      ] 
 
     } 
 
     ]; 
 
});
li{ 
 
    list-style: none; 
 
    background-color:#334559; 
 
    color:#FFF; 
 
    padding:2px; 
 
    cursor: pointer; 
 
    
 
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.2/css/font-awesome.min.css" rel="stylesheet"/> 
 

 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
    
 

 
    
 
<div ng-app="mainApp" ng-controller="mainCtrl"> 
 
    <script type="text/ng-template" id="treeNodes.html"> 
 
    <ul> 
 
     <li ng-repeat="node in nodes" > 
 
     <div ng-click="node.expand = (node.expand?false:true);" ><i class="fa" ng-class="{'fa-caret-right':(node.node.length && !node.expand), 'fa-caret-down':(node.node.length && node.expand)}"></i>&nbsp;{{node.name}}</div> 
 
     <div ng-show="node.node.length && node.expand" ng-include=" 'treeNodes.html' " onload="nodes = node.node"></div> 
 
     </li> 
 
    </ul> 
 
                           </script> 
 
    <div ng-include=" 'treeNodes.html'" style="overflow-y: auto;height: 55%;width: 300px;"></div> 
 
</div>

+1

Dzięki za odpowiedź. Jak wyświetlić węzły podrzędne na kliknięciu węzła nadrzędnego? –

+0

@ManojSuthar Edytowałem odpowiedź – byteC0de

+0

@ManojSuthar sprawdź aktualizację teraz – byteC0de

1

Jednym z rozwiązań może być stworzenie dyrektywy, która dba o działanie rekursywne do dowolnego ograniczenia.

Uwaga: To rozwiązanie jest ogólnym drukarka json + edytor kanciasty, że stworzony dla jednego z moich zastosowań

JsonApp.directive('renderInput',['$compile','NODE_RELATION_CONFIG',function($compile){ 

    var getTemplate = function(inputKey,inputValue,inputParent,inputConfig,inputDisabled,inputHidden){ 
     var template = ''; 
     var disabled = (inputDisabled || (inputConfig && inputConfig["disabled"])) ? true : false; 
     var hidden = (inputHidden || (inputConfig && inputConfig["hidden"])) ? true : false; 

     if(typeof(inputConfig)=="undefined") 
      inputConfig ={} 

     for(var key in inputParent) 
     { 
      if(typeof(inputConfig[key])=="undefined") 
       inputConfig[key] = {}; 
     } 



     if(typeof(inputValue)=="object") 
     { 

      //template = '<div ng-hide="'+hidden+'" style="padding-left:7%;border:1px solid #ddd;"><div class="pheading">{[{ inputKey }]}</div><div id="render-123" ng-repeat="(key,value) in inputValue" render-input input-key="{[{ key}]}" input-parent="inputValue" input-value="value" input-config="inputConfig[key]" input-disabled="'+disabled+'" input-hidden="'+hidden+'"></div></div>'; 
      template = '<div ng-hide="'+hidden+'"><div id="render-123" ng-repeat="(key,value) in inputValue" render-input input-key="{[{ key}]}" input-parent="inputValue" input-value="value" input-config="inputConfig[key]" input-disabled="'+disabled+'" input-hidden="'+hidden+'"></div></div>'; 
     } 
     else 
     { 

      var fieldHeading = (inputConfig && inputConfig["mapped_name"]) ? inputConfig["mapped_name"]: inputKey; 
      if(typeof(inputValue)!="string" || inputValue.length < 200) 
      { 
       //small fields use input type text 

       template = '<div ng-hide="'+hidden+'"><h3 class="gi-orange dy-field-title">'+fieldHeading+'</h3><input class="dy-id-input" type="text" value="{[{ inputValue }]}" ng-disabled="'+disabled+'" /></div>'; 


      } 
      else 
      { 
       template = '<div ng-hide="'+hidden+'"><h3 class="gi-orange dy-field-title">'+fieldHeading+'</h3><textarea class="dy-id-textarea" type="text" ng-disabled="'+disabled+'">{[{ inputValue }]}</textarea></div>'; 
      } 
     } 
     return template 
    } 

    return{ 
     scope:{ 
      inputKey:"@", 
      inputValue:"=", 
      inputParent:"=", 
      inputConfig:"=", 
      inputDisabled:"=", 
      inputHidden: "=" 
     }, 



     link : function(scope, element, attrs) { 

      element.html(getTemplate(scope.inputKey,scope.inputValue,scope.inputParent,scope.inputConfig,scope.inputDisabled,scope.inputHidden)).show(); 

      $compile(element.contents())(scope); 
      $(element).on('change','input,textarea',function(e){ 
       if(!scope.$$phase) 
        scope.inputParent[scope.inputKey]=$(this).val(); 
       if(!scope.$$phase) 
        scope.$apply(); 
       e.stopImmediatePropagation(); 
      }) 

     }, 

     restrict: 'AE' 
    } 
}]); 

Przykładowy config:

{"flight_sector": {"additional_fields": ["at.scdl_pg.content", "at.scdl_pg.meta.keywords", "at.scdl_pg.meta.title", "at.scdl_pg.meta.desc"], "fields_mapped_names": {"at|scdl_pg|meta|desc": "Flight Sector Page : Meta Description", "at|scdl_pg|meta|keywords": "Flight Sector Page : Meta Keywords", "at|score|flier": "Flight Sector Flier Score", "at|scdl_pg|content": "Flight Sector Page : Content Html", "at|scdl_pg|meta|title": "Flight Sector Page : Meta Title", "at|type": "Flight Sector Type"}, "disabled_fields": ["at.score.flier", "at.type"], "hidden_fields": ["at.airlines", "_id", "s", "e", "sn", "en", "st", "t"], "settings": {"en": {"hidden": 1}, "e": {"hidden": 1}, "st": {"hidden": 1}, "s": {"hidden": 1}, "at": {"scdl_pg": {"content": {"mapped_name": "Flight Sector Page : Content Html"}, "meta": {"keywords": {"mapped_name": "Flight Sector Page : Meta Keywords"}, "title": {"mapped_name": "Flight Sector Page : Meta Title"}, "desc": {"mapped_name": "Flight Sector Page : Meta Description"}}}, "score": {"flier": {"disabled": 1, "mapped_name": "Flight Sector Flier Score"}}, "type": {"disabled": 1, "mapped_name": "Flight Sector Type"}, "airlines": {"hidden": 1}}, "t": {"hidden": 1}, "_id": {"hidden": 1}, "sn": {"hidden": 1}}}, "routes_map": {"additional_fields": ["at.rpr_pg.desc"], "fields_mapped_names": {"at|rpr_pg|desc": "Routeplanner Page Write-Up"}, "hidden_fields": ["routes", "t", "s", "e", "sn", "en", "_id"], "settings": {"en": {"hidden": 1}, "e": {"hidden": 1}, "s": {"hidden": 1}, "t": {"hidden": 1}, "routes": {"hidden": 1}, "_id": {"hidden": 1}, "at": {"rpr_pg": {"desc": {"mapped_name": "Routeplanner Page Write-Up"}}}, "sn": {"hidden": 1}}}} 

Uwaga: Ta przykładowa konfiguracja zajmuje się dodatkowymi polami, które chcesz dodać ing json + jeśli chcesz ukryć tylko kilka pól + zachować niektóre pola wyłączone jako pola wejściowe.

Powiązane problemy