Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meteor: How to create reactive tree structure from a collection

Tags:

tree

meteor

I am using the most recent meteor version, and this is a local deployment. I have a collection (Folders) that contains a tree structure, in which children nodes have parent node id as an attribute. I'd like to display the tree in a UI tree widget. I've studied the recursive template topics, however, I have a hard time to get children nodes displayed. Here are the relevant template and code.

<template name="sideTreeTemplate">
  <div id="tree" style="height: 200px">
    <h2 class="panel">My Data</h2>
    <ul id="treeData" style="display: none;">
      {{#each treeItems }}
        {{> treeNodeTemplate}}
      {{/each }}
    </ul>
  </div>
</template>


<template name="treeNodeTemplate" >
  <li id="{{id}}" title="{{name}}" class="{{type}}">
    {{name}}
    {{#if hasChildren}}
      <ul>
        {{#each children}}
          {{> treeNodeTemplate}}
        {{/each}}
      </ul>
    {{/if}}
  </li>
</template>

The client.js code:

Template.sideTreeTemplate.treeItems = function() {

  var items = Folders.find({"parent" : null});
  console.log("treeItems length=" + items.count());
  items.forEach(function(item){
    item.newAtt = "Item";
    getChildren(item);
  }); 
  return items;

};


var getChildren = function(parent) {
  console.log("sidetree.getChildren called");
  var items = Folders.find({"parent" : parent._id});
  if (items.count() > 0) {
    parent.hasChildren = true;
    parent.children = items;
    console.log(
        "children count for folder " + parent.name +
        "=" + items.count() + ",
        hasChildren=" + parent.hasChildren
    );
    items.forEach(function(item) {
      getChildren(item);
    });
  }
};

The top level of the tree shows up fine, and is reactive, but none of the children are shown, even though the getChildren function is called for nodes with children. My suspicion is that the server sync actually removed the dynamically added properties (i.e. hasChildren, children) for each node. In this case, how can I make reactive tree working? Or maybe it is something else wrong with my implementation?

Thanks for the help.

like image 975
user2680514 Avatar asked Mar 22 '23 19:03

user2680514


1 Answers

The simple way is not to add children objects as properties of the parent object. Instead, use a helper:

Template.treeNodeTemplate.hasChildren = function() {
  return Folders.find({parent: this._id}).count() > 0;
};

Template.treeNodeTemplate.children = function() {
  return Folders.find({parent: this._id});
};
like image 55
Hubert OG Avatar answered Apr 25 '23 11:04

Hubert OG