Ractive.js来自具有父关系的单个项目数组的嵌套列表

时间:2014-03-26 18:46:23

标签: javascript templates handlebars.js ractivejs

您有一个包含idparentidmessage属性的项目列表。 parentid引用同一列表中的其他项。嵌套级别没有限制。你会如何实现这个?

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

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>

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

甚至比什么是模板的最佳实现是递归渲染自己直到什么都没有留下?

1 个答案:

答案 0 :(得分:2)

使用ractive.js,您可以使用javascript使用部分和表达式帮助函数来过滤数组(有关完整示例,请参阅http://jsfiddle.net/pUf5P/1/

模板:

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

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

设定:

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

或者对于纯模板解决方案(请参阅http://jsfiddle.net/pUf5P/2/),您可以执行以下操作:

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

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

更新:我知道你想要这样做“没有遍历整个数组,建立一个新的”,但是意识到你在每个级别循环遍历整个数组以找到匹配的子节点。您不需要构建层次结构,只需根据父ID进行存储(参见http://jsfiddle.net/pUf5P/3/):

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

然后使用上述模板策略的变体:

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

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

  </ul>
<!-- {{/lister}} -->