Modèle récursif avec knock-out js

Est-il possible de créer un modèle récursif uniquement avec knock-out js?

J'ai un objet knock-out:

function FormElementNode(children, text, value) { var self = this; self.children = ko.observableArray(children); self.text = ko.observable(text); self.value = ko.observable(value); } 

Les enfants sont un ensemble de FormElementNode.

Je veux le dessiner et les enfants sont récursivement dans un noeud de liste hiérarchique:

 <ul> <li>Parent text value: Children: <ul> <li>Child1 text value</li> <li>Child2 text value</li> </li> 

Merci!

Oui KnockOut prend en charge les modèles récursifs afin que vous puissiez faire référence et rendre le même modèle dans le modèle.

Un exemple de html dans votre cas ressemblerait à ceci:

 <script id="formElementNodeTemplate" type="text/html"> <ul> <li>Parent <span data-bind="text: text"></span> <span data-bind="text: value"></span> <br/> Children: <!-- ko template: { name: 'formElementNodeTemplate', foreach: children } --> <!-- /ko --> </li> </ul> </script> <div data-bind="template: { name: 'formElementNodeTemplate', data: $data }"> </div> 

Demo JSFiddle.

Je pense que j'ai une solution un peu meilleure sans racine d'arbre . S'il vous plaît, jetez un oeil:

http://jsfiddle.net/nonsense66/Bzekr/

Modèle:

 <script id="treeElement" type="text/html"> <li> <span data-bind="text: name"></span> <ul data-bind="template: { name: 'treeElement', foreach: children }"> </ul> </li> </script> <ul data-bind="template: { name: 'treeElement', foreach: $data.treeRoot }"></ul> 

Javascript:

 var viewModel = { treeRoot: ko.observableArray() }; var TreeElement = function(name, children) { var self = this; self.children = ko.observableArray(children); self.name = ko.observable(name); } var tree = [ new TreeElement("Russia", [ new TreeElement("Moscow") ]), new TreeElement("United States", [ new TreeElement("New York", [ new TreeElement("Harlem"), new TreeElement("Central Park") ]) ]) ]; viewModel.treeRoot(tree); ko.applyBindings(viewModel); 

J'espère que cela aide!

Cette publication m'a été d'une grande aide. Je trouve toujours de nouvelles façons d'utiliser knock-out. Je voulais simplement ajouter une modification utile qui fait exactement ce que nemesv propose uniquement en utilisant le plugin ko.mapping.

 //Nested javascript object: var formElementNode = { children: [{ children: [], text: 'Child1', value: 'Value1' }, { children: [{ children: [{ children: [], text: 'Child2.1.1', value: 'Value2.1.1' }], text: 'Child2.1', value: 'Value2.1' }], text: 'Child2', value: 'Value2' }, { children: [], text: 'Child3', value: 'Value3' }], text: 'Main', value: 'MainValue' }; //Use ko.mapping to generate viewModel: var viewModel = ko.mapping.fromJS(formElementNode); ko.applyBindings(viewModel); 

Comme cela a été démontré dans ce jsFiddle .

Reliure personnalisée récursive

Une autre solution, après avoir lu ces modèles, était plus lente, je regardais avec une liaison récursive.

<ul data-bind="nestMe: name"></ul>

 ko.bindingHandlers.nestMe = { init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { }, update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { var observable = valueAccessor() || { }; var unwrapped = ko.unwrap(observable); ko.utils.setHtml(element, '<li>'+unwrapped+'<ul data-bind="foreach: children"><li data-bind="nestMe: name" /></ul></li>'); } }; var rootModel = function(name, children) { this.name = ko.observable(name); this.children = ko.observableArray(children); }; var basemodel = new rootModel('test'); basemodel.children.push(new rootModel('aaa',[new rootModel('111'),new rootModel('222')])); basemodel.children.push(new rootModel('bbb')); basemodel.children.push(new rootModel('ccc',[new rootModel('333'),new rootModel('444')])); ko.applyBindings(basemodel); 

Avoir la possibilité de jouer avec les données avant la récurrence devrait être utile.

JSFiddle