包裹骨干集合中的项目?

时间:2013-12-12 04:36:12

标签: backbone.js backbone.js-collections

我一直在遇到一些令人困惑的解决方案,以及使用主干将不匹配的项目包装到div中的方法。

我只是为自己构建一个简单的示例,并希望将所有模型嵌套在具有相同属性team的集合中,使用comparator可以很好地组织列表,但是在我的生活中,我无法找到一个明确的解决方案来包装每一个,这样我就可以更好地控制团队内players的列表。

像我这样的初学者必须有一个明确的简单解决方案。我真的只想让事情变得干净简单。我想要的html结果如下所示。

<div class="pacers">
    <li>Paul</li>
    <li>Roy</li>
</div>
<div class="bulls">
    <li>Kirk</li>
    <li>Taj</li>
</div>

基于骨干友好的json数组,如下所示。

 [
  {
    "name": "Paul",
    "team": "pacers"
  },
  {
    "name": "Kirk",
    "team": "bulls"
  },
  {
    "firstname": "George",
    "team": "pacers"
  },
  {
    "name": "Taj",
    "team": "bulls"
  }
]

所以使用比较器很棒我只是写这个comparator : 'team'并且它为我处理列表顺序,很酷,但我没有太多的控制我想将列表包装在更分层的系统中。

3 个答案:

答案 0 :(得分:1)

另一种方法:

如果您使用underscore's模板,这可能是一种方法。您可以使用underscore's groupBy功能根据团队对列表进行分组。

var teams = [
  {
    "name": "Paul",
    "team": "pacers"
  },
  {
    "name": "Kirk",
    "team": "bulls"
  },
  {
    "firstname": "George",
    "team": "pacers"
  },
  {
    "name": "Taj",
    "team": "bulls"
  }
];
var groupedList = _.groupBy(list, function(l){
    return l.team;
});
console.log(JSON.stringify(groupedList));

这是如何分组的。

{
    "pacers": [
        {
            "name": "Paul",
            "team": "pacers"
        },
        {
            "firstname": "George",
            "team": "pacers"
        }
    ],
    "bulls": [
        {
            "name": "Kirk",
            "team": "bulls"
        },
        {
            "name": "Taj",
            "team": "bulls"
        }
    ]
}

然后,您可以在每个循环和模板中使用,并按以下方式生成HTMLgroupedListteams传递给模板下方。

<%
   _.each(teams, function(team, teamName){
%>
   <div class="<%=teamName%>">
<%
   _.each(team, function(player){
%>
    <li><%=player.name%></li>
<%
   });
%>
    </div>
<%
   });
%>

这会以您预期的方式生成HTML

注意:

考虑underscore模板提供代码段,您可能必须根据您使用的内容进行更改。希望它有所帮助。

答案 1 :(得分:1)

如果我错了,请纠正我,所描述的问题更多地涉及控制与其模型相关的每个项目的内容以及如何简单地将它们分组渲染。

1)Niranjan已经将数据分组到单独的列表中,但请记住,返回的列表不是Backbone构造。

2)根据手册,你应该通过集合获得'_.groupBy'方法,即:。

myCollection.groupBy(等);

3)我个人会考虑将groupBy的结果映射回模型,并将每个模型传递到一个单独的视图中,并在主列表视图中呈现它们。

var CollectionView = Backbone.View.extend({
    initialize : function () {
       // Note: I am pretending that you have a real collection.
       this.collection.fetch().then(
         this.addAll(true);
       );
    }

    addOne : function (model) {
      // call .render individual template items here for each model.
      var view = new ItemView(model);
      this.$el.append(view.render();
    },

    addAll : function (groupOpts) {
      var col = this.collection;

      if(groupOpts === true) { 
         // Do grouping (or do it in the model). Maybe put back into new collection?
      }         

      _.each(col, function(model) {
         this.addOne(model);
      }, this);
    },

    render : function () {
      // Render your template here.                    
    }
});

var ItemView = Backbone.View.extend({
   render : function () {

   }
});

不是一个完整的例子,但这是我在尝试同样的事情时会遵循的一般模式。在我看来,拥有每个项目的个人视图/模型可以让您获得更多控制权。

答案 2 :(得分:0)

这可以在一个非常疯狂的视图模板中处理(取决于你的模板语言)...或者你可以使用更简单的模板/视图,只是做一些更疯狂的集合查询(首先使用pluck来获得团队,取消那个数组,然后为每个团队运行一些地方......但你可以看到这是多么疯狂)

我投票支持视图,视图模板应该处理这个......你在用什么?玉?小胡子?

这样的东西 - 逻辑伪代码,因为我不知道你的模板语言:

var team;
forEach player in players 
if(!team) {
   set team = player.team
   print open holder and then the first row
} (team !== player.team {
   set team = player.team
   print close of previous holder, then open holder and then the first row of new team
} else {
   print just the player row
}

即便如此,你可以看到它本身有点脏......但是你所描述的是一个视图/表示问题,你可以在这里做,没有新的额外循环和地图和wheres(就像你在调用视图之前在数据层中做到的那样你必须做的事情)