R
R
reactreact2015-12-11 19:42:19
JavaScript
reactreact, 2015-12-11 19:42:19

How to correctly display all data from the database into a table in meteor?

{
"_id" : "kCwbRfsi9wLTwciGL",
"title" : "Test"
},
{
"_id" : "2RxhjiuBA5Nf7KtWu",
"title" : "Test1"
},
{
"_id" : "78gGbshheCsDPoWZk",
"title" : "Test2"
},
{
"_id" : "sMkY3QnAmg3uxtXkq",
"title" : "Child",
"parentId" : "2RxhjiuBA5Nf7KtWu"
 },
 {
"_id" : "wMkf5QnAmg3nutMkq",
"title" : "Child1",
"parentId" : "2RxhjiuBA5Nf7KtWu"
 }

You need to display it on the page to get the following structure:
<ol>
<li><div>Test</div></li>
<li><div>Test1</div>
 <ol>
<li><div>Child</div></li>
<li><div>Child1</div></li>
</ol>
</li>
<li><div>Test2</div></li>
</ol>

And I don't know how many nested elements can be. How to get it right?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
evilandfox, 2016-03-05
@evilandfox

An interesting problem) It's a pity I didn't see it earlier.
You can solve it using the Underscore library built into Meteor and recursion :).
Let there be such test data:

const _id1 = Items.insert({title: 'Item 1'});
const _id2 = Items.insert({title: 'Item 2'});
  const _id21 = Items.insert({title: 'Item 2.1', parent: _id2});
  const _id22 = Items.insert({title: 'Item 2.2', parent: _id2});
    const _id221 = Items.insert({title: 'Item 2.2.1', parent: _id22});
    const _id222 = Items.insert({title: 'Item 2.2.1', parent: _id22});
  const _id23 = Items.insert({title: 'Item 2.3', parent: _id2});
const _id3 = Items.insert({title: 'Item 3'});
  const _id31 = Items.insert({title: 'Item 3.1', parent: _id3});
const _id4 = Items.insert({title: 'Item 4'});
const _id5 = Items.insert({title: 'Item 5'});

We receive them
Now we represent this data in the form of a tree. Each leaf of the tree is an object with a value titleand children children. We build such a tree through the following function:
function getAsTree(items) {
  // для корневых элементов ставим _id родителя пустой строкой ''
  var extItems = _.map(items, function(item){
    if ('parent' in item)
      return item;
    else
      return _.extend(item, {parent: ''});
  });
  // данная функция рекурсивно возвращает потомков элемента с заданным _id,
  // которые в свою очередь также содержат потомков и т.д.
  // если же потомка у элемента нет, то в нем {children: []}
  function recBuildTree(_id){
    var result = [];
    return _.map(_.filter(extItems, function(item){
      return item.parent === _id;
    }), function(item){
      return _.extend(item, {
        children: recBuildTree(item._id)
      });
    });
  }
  // определяем корень дерева, который не содержит значения,
  // а его потомки - корневые элементы с {parent: ''}
  var tree = {
    title: '',
    _id: '',
    children: recBuildTree('')
  };
  return tree;
}

Now let's create a template that uses the helper for rendering, then display the generated tree in it:
Template.listView.helpers({
  children: function(){
    return getAsTree(Items.find().fetch()).children;
  }
});

<template name="listView">
  <ol>
    {{#each children}}
      {{> _listViewItem}}
    {{/each}}
  </ol>
</template>

<template name="_listViewItem">
<li>
  <div>{{title}}</div>
  {{#if children}}
    <ol>
      {{#each children}}
        {{> _listViewItem}}
      {{/each}}
    </ol>
  {{/if}}
</li>
</template>

Result:
Note that non-root elements with a non-existent parent will not be included in the tree.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question