Pregunta

I want to clik ul li items and collapse and open them. Working code is here

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("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")
    ])
];

viewModel.treeRoot(tree);

ko.applyBindings(viewModel);

html like this

<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>
¿Fue útil?

Solución

You need to introduce a flag isCollapsed on your TreeElement which you can toogle from a click binding event handler.

And based on that isCollapsed you need to filter out your children collection with a help of a computed observable:

var TreeElement = function(name, children) {
   var self = this;
   self.children = ko.observableArray(children);
   self.isCollapsed = ko.observable();
   self.collapse = function() {
       self.isCollapsed(!self.isCollapsed());
   }
   self.visibleChildren = ko.computed(function(){
       if (self.isCollapsed())
           return [];
       return children;
   });
   self.name = ko.observable(name);
}

And you need to update your template with the click binding handler and use the visibleChildren instead of the children collection:

<script id="treeElement" type="text/html">
  <li>
     <span data-bind="text: name, click: collapse"></span>
     <ul data-bind="template: { name: 'treeElement', foreach: visibleChildren }">
     </ul>
  </li>
</script> 

Demo JSFiddle.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top