2016-06-20 9 views
0

Ich versuche diese rekursive Vorlage, aber ich bin bei dynamischen Datenrendern stecken. Meine Daten wie folgt aussieht:Rekursives Array in Knockout

[Object 
    Children: Array[2] 
    EventCategory: Object 
] 

Bisher habe ich diese Vorlage als pro jsfiddle Beispiel, aber wie zu überprüfen, ob das Array Kind?

<script id="categoryTemplate" type="text/html"> 
     //How to check if data has child and display the child to its parent? 
     <li> 
      <span data-bind="text: name"></span> 
      <ul data-bind="template: { name: 'categoryTemplate', foreach: children }"></ul> 
     </li> 
    </script> 

HTML-Darstellung:

<ul data-bind="template: {name: 'categoryTemplate', foreach: $data.categoryRoot}"></ul> 

Knockout-Bindung, wie das Array zu machen?

var categoryElement = function (name, children) { 
    var self = this; 
    self.children = ko.observableArray(children); 
    self.name = ko.observable(name); 
} 

var categoryModel = { 
    categoryRoot: ko.observableArray() 
}; 

var viewModel = function() { 
    var me = this; 
    me.categoryRoot = ko.observableArray(); 

     me.selectCategory = function() { 
      $.get('link-to-get-categories').then(function(response) { 
       var categoryData = [ 
       //new categoryElement("Russia", [ 
       // new categoryElement("Moscow") 
       //]), 
       new categoryElement(response.Data) 

       //me.categoryRoot(categoryData); 
       me.categoryRoot(response.Data); 
      }); 
     } 
} 

ko.cleanNode($('#addEvent')[0]); 
ko.applyBindingsWithValidation(new viewModel(), $('#addEvent')[0]); 
+0

Sie einen Screenshot Ihrer Daten nicht veröffentlichen, dass nutzlos. Veröffentlichen Sie Ihre Daten. – Tomalak

+0

Es zeigt nur, wie meine Datenstruktur aussieht – naru

+0

Ich weiß, aber das Einfügen der * tatsächlichen Daten * ist unendlich viel nützlicher als ein statischer Screenshot Ihrer Browser-Konsole. Beim nächsten Mal posten Sie einfach Ihre Daten. – Tomalak

Antwort

0

, wie wenn das Array Kind überprüfen?

Sie können wie so in einem Daten-bind für Kinder überprüfen:

<-- ko if: children().length --> 
<ul></ul> 
<-- /ko --> 

Vereinfachen Sie die Daten-bind durch eine in Ihrem Viewmodel berechnet erstellen:

self.hasChildren = ko.pureComputed(function() { 
    return self.children().length; 
}); 
0

<-- ko if: children && children().length --> 
 
<ul></ul> 
 
<-- /ko --> Safe check

0

Konzeptioneller Fehler: Ihre Baumwurzel ist selbst keine Liste. Es ist ein einzelnes Baumelement. Mit anderen Worten, verwenden Sie kein Array für den Baumstamm.

Ich würde auch die Baum-Gebäude-Vorlage umdrehen, so dass es vollständig in sich abgeschlossen ist.

Abgesehen davon, knockout virtuelle Elemente und die if Bindung kann das bedingte Rendering aussortieren.

var TreeElement = function(name, children) { 
 
    var self = this; 
 
    self.children = ko.observableArray(children); 
 
    self.name = ko.observable(name); 
 
}; 
 

 
var viewModel = { 
 
    treeRoot: new TreeElement(null, [ 
 
     new TreeElement("Russia", [ 
 
      new TreeElement("Moscow") 
 
     ]), 
 
     new TreeElement("Germany"), 
 
     new TreeElement("United States", [ 
 
      new TreeElement("Atlanta"), 
 
      new TreeElement("New York", [ 
 
       new TreeElement("Harlem"), 
 
       new TreeElement("Central Park") 
 
      ]) 
 
     ]), 
 
     new TreeElement("Canada", [ 
 
      new TreeElement("Toronto") 
 
     ]) 
 
    ]) 
 
}; 
 

 
ko.applyBindings(viewModel);
.tree { 
 
    border: 1px solid blue; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<script id="tree" type="text/html"> 
 
    <!-- ko if: children().length --> 
 
    <ul class="tree" data-bind="foreach: children"> 
 
     <li> 
 
      <span data-bind="text: name"></span> 
 
      <!-- ko template: 'tree' --><!-- /ko --> 
 
     </li> 
 
    </ul> 
 
    <!-- /ko --> 
 
</script> 
 

 
<div data-bind="template: {name: 'tree', data: treeRoot}"></div>

+0

basierend auf Ihrem Snippet, dem 'treeRoot'-Wert, an dem ich festhalte, wie soll ich den dynamischen Wert davon basierend auf' response.Data'-Screenshot laden? – naru

+0

Ich vermute 'treeRoot: neues TreeElement (null, response.Data)' - vorausgesetzt, dass 'response.Data' ein Array ist. Der 'TreeElement'-Konstruktor sollte dann darauf achten, seine eigenen untergeordneten 'TreeElement'-Objekte zu erzeugen. – Tomalak