【问题标题】:flat list from nested elements in marionette来自木偶中嵌套元素的平面列表
【发布时间】:2014-08-12 11:11:43
【问题描述】:

是否可以在 Marionette 中从嵌套的模型和集合列表中生成平面列表?

例如,我想生成一个选择元素,每个节点作为一个选项(子选项应该缩进):

[
  {
    nodeName: "top level 1",
    nodes: [
      {
        nodeName: "2nd level, item 1",
        nodes: [
          { nodeName: "3rd level, item 1" },
          { nodeName: "3rd level, item 2" },
          { nodeName: "3rd level, item 3" }
        ]
      },
      {
        nodeName: "2nd level, item 2",
        nodes: [
          { nodeName: "3rd level, item 4" },
          { nodeName: "3rd level, item 5"},
          { nodeName: "3rd level, item 6" }
        ]
      }
    ]
  }
]

这应该变成这样:

<select>
    <option>top level 1</option>
    <option>   2nd level, item 1</option>
    <option>      3nd level, item 1</option>
    <option>      3nd level, item 2</option>
    <option>      3nd level, item 3</option>
    <option>   2nd level, item 2</option>
    ...
</select>

到目前为止,我一直在尝试使用嵌套复合视图(如在这个小提琴http://jsfiddle.net/hoffmanc/NH9J6/ 中),但我无法使其正常工作。

问候

【问题讨论】:

  • 这里是你的 fiddle jsfiddle.net/leighking2/NH9J6/219 的运行版本,删除了原始 github 依赖项,将一些替换为 cdn 版本,而其他一些没有被使用,所以我只是删除了它们。还将itemView 更改为treeRoot 上的chiewView,因为它在木偶2.* 中已更改为。那么您是否希望在渲染时显示缩进?
  • 好的,谢谢!我懂了!小提琴不是我的,但我只是将它作为如何从嵌套模型/集合转到嵌套 ul 列表的一般方法。我只想从嵌套模型/集合转到平面选项列表。然后缩进只是为了向用户可视化“嵌套结构”。

标签: backbone.js marionette


【解决方案1】:

当然,首先递归迭代嵌套并使用节点文本和嵌套级别创建纯 JSON:

var flat = [];

function parseJson(nodes){
    parseJson.level = parseJson.level || 0;        

    nodes.forEach(function(node, i){
        flat.push({ text:node.name, level: parseJson.level});
        if(node.nodes){
            parseJson.level++;
            parseJson(node.nodes);
        } 
        (i == nodes.length -1) && parseJson.level--;
    })
}

/* or you can get flat array with reduce */

var rawJson = [/* Your json here */], 
    flat = rawJson.reduce(function rec(memo, item, i, array){
        rec.level = rec.level || 0;
        memo.push({ text: item.n, level: rec.level });
        if(item.nodes){
            rec.level++;  
            item.nodes.reduce(rec, memo);
        }

        (i == array.length -1) && rec.level--;

        return memo;
}, []);

nodes 是您的原始 json。在flat 中,您将拥有这样的元素:

{
    text: 'node text',
    level: 2
}

接下来,为视图渲染创建模型和集合:

var NodeModel = Backbone.Model.extend({
        defaults: {
            name: 'unnamed',
            level: 0
        }
    }),
    NodeCollection = Backbone.Collection.extend({
        model: NodeModel 
    });

然后查看:

var NodeView = Marionette.ItemView.extend({
        tagName: 'option',
        template: '#node-template'
    }),
    NodeCollectionView =  Marionette.CollectionView.extend({
        itemView: NodeView /* or childView if Marionette v 2.0.*/
    });

然后是模板:

<% _.times(level, function(){ %> &nbsp; <% }); %> <%= text %>

最后:

(new NodeCollectionView({
  collection: new NodeCollection(flat),
  el: 'body'
})).render();

仅此而已)希望对您有所帮助;

【讨论】:

    【解决方案2】:

    您是否考虑过使用 underscore.js 的 _.flatten() 方法?它可以简单得多。 flattening nested arrays/objects in underscore.js

    【讨论】:

      猜你喜欢
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-16
      • 1970-01-01
      • 2020-12-03
      相关资源
      最近更新 更多