【问题标题】:Ractive.js Nested list from a single array of items with parent relationship来自具有父关系的单个项目数组的 Ractive.js 嵌套列表
【发布时间】:2014-03-26 18:46:22
【问题描述】:

您有一个具有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>

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

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

【问题讨论】:

  • 假设最后一个数据项id: 5,应该是parentid: 2,而不是parentid: 1
  • 想要解决这个问题,但“编辑必须至少有 6 个字符”:/

标签: javascript templates handlebars.js ractivejs


【解决方案1】:

使用 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}} -->

【讨论】:

  • 是的。执行一个循环来生成存储桶比纯模板或过滤解决方案要快得多。不知道我还期待什么:/谢谢答案:)
猜你喜欢
  • 2017-09-29
  • 2020-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
  • 1970-01-01
相关资源
最近更新 更多