1

您有一个带有 、 和 属性的id项目parentid列表messageparentid引用同一列表中的其他项目。嵌套级别没有限制。你将如何实现这一点?

换句话说,如何采取这个:

var data = [
    {
        id: 1,
        parentid: 0,
        message: "I'm 1, and I have no parent."
    }, {
        id: 2,
        parentid: 1,
        message: "I'm 2, and 1 is my parent."
    }, {
        id: 3,
        parentid: 1,
        message: "I'm 3, and 1 is my parent."
    }, {
        id: 4,
        parentid: 0,
        message: "I'm 4, and I have no parent."
    }, {
        id: 5,
        parentid: 1,
        message: "I'm 5, and 2 is my parent."
    }
];

并把它变成这样:

<ul>
    <li>
        I'm 1, and I have no parent.
        <ul>
            <li>
                I'm 2, and 1 is my parent.
                <ul>
                    <li>
                        I'm 5, and 2 is my parent.
                    </li>
                </ul>
            </li>
            <li>
                I'm 3, and 1 is my parent.
            </li>
        </ul>
    </li>
    <li>
        I'm 4, and I have no parent.
    </li>
</ul>

有没有一种很好又快速的方法可以在模板中做到这一点?没有遍历整个数组,构建一个新数组并渲染它?

甚至,递归渲染自身直到什么都没有的模板的最佳实现是什么?

4

1 回答 1

2

With ractive.js, you could use javascript to filter the array using a partial and an expression helper function (see http://jsfiddle.net/pUf5P/1/ for full example)

Template:

{{# { index: 0 } }}
{{>lister}}
{{/ }}

<!-- {{>lister}} -->
  <ul>
  {{# filter(list, .index) }}
    <li>{{message}}
      {{# { index: id } }}
         {{>lister}}
      {{/ }}
   </li>
  {{/ }}
  </ul>
<!-- {{/lister}} -->

Setup:

new Ractive({
    el: 'body',
    template: '#template',
    data: { 
        list: data,
        filter: function(list, parent){
            return list.filter(function(item){
                return item.parentid === parent
            })
        }      
    }
})

Or for a pure template solution (see http://jsfiddle.net/pUf5P/2/), you can do:

{{# { index: 0 } }}
{{>lister}}
{{/ }}

<!-- {{>lister}} -->
  <ul>
    {{#list}}
    {{# .parentid === index}}
    <li>{{message}} 
      {{# { index: .id } }}  
        {{>lister}}
      {{/ }}   
    </li>
    {{ /}}
  {{/list }}
  </ul>
<!-- {{/lister}} -->

UPDATE: I know you wanted to do this "Without looping through the whole array, building a new one", but realize that you are looping through the whole array at each level to find the matching children. You don't need to build a hierarchical structure, just bucket the items based on parent id (see http://jsfiddle.net/pUf5P/3/):

var byParent = {}
data.forEach(function(item){
    if(!byParent[item.parentid]){ byParent[item.parentid] = [] }
    byParent[item.parentid].push(item)
})

Then use a variant of the above template strategy:

{{# { index: 0 } }}
{{>lister}}
{{/ }}

<!-- {{>lister}} -->
  <ul> 
    {{# { list: byParent[index]} }}
      {{#list}}
      <li> {{(.message)}}
        {{# { index: .id } }}
        {{>lister}}
        {{/ }}            
      </li>
      {{/list}}
    {{/ }}

  </ul>
<!-- {{/lister}} -->
于 2014-03-27T22:14:05.360 回答