如何在集合中添加集合?

时间:2013-11-29 02:13:16

标签: javascript backbone.js

问题:我正在使用backbone.js我有一个播放器的player视图,此视图的根元素是<li></li>列表项节点。

然后我有一个显示集合中所有玩家的players视图,此视图的根元素是<ul></ul>。 (非常简单的东西!)

结果就是。

<ul> //The players collection root for the players collection view
    <li>Kobe Bryant is on the lakers</li> // The player model root element for the player model view
    <li>LeBron James is on the heat</li> // The player model root element for the player model view
</ul>

我的模型属性由name, team组成。

[
    {name: 'Kobe Bryant', team: 'lakers'},
    {name: 'LeBron James', team: 'heat'}
]

如何循环(或做任何最好的事情),以便我的视图结果如下。

<ul class="lakers"> 
    <li>Kobe Bryant is on the lakers</li>
</ul>
<ul class="heat"> 
    <li>LeBron James is on the heat</li>
</ul>

更好我不需要进行团队合集视图。然后写一些代码来匹配每个玩家和他的团队?结果是这样的结果。

<div class="lakers">// Teams collection root element
    <ul>// Players collection root element 
        <li>Kobe Bryant is on the lakers</li>// Player model root elemnt
    </ul>
</div>
<div class="heat">// Teams collection root element
    <ul>// Players collection root element 
        <li>LeBron James is on the heat</li>// Player model root elemnt
    </ul>
</div>

我尝试了这个但是我在思考我实例化每个视图的方式是错误的,或者我只是做错了什么,所以如果把一组玩家放在一个团队中是个好主意,我得到一个像上面这样的结果,我可以拥有一个父元素作为团队,然后是该团队里面的玩家列表?


我的想法&amp;代码:我在players视图中思考我可以写一些东西来按团队组织每个模型,比如。

_.each(this.collection.where({team: "lakers"}), function(model) {
       var playerView = new PlayerView({ model: model});
       this.$el.append(playerView.render().el);
       this.$el.addClass('lakers');
}, this);

这有明显的问题因为,我们写这一切只是为了向根添加一个类,如果我们再次这样做,它将继续添加到根<ul class="lakers miami">这没有用。< / p>

我的想法很少,我得到的照片我知道我想对每个玩家进行分类,但我无法弄明白。我倾向于一个球队集合的球员集合,我只是困惑如何匹配this.team.get('name') == this.player.get('name') //相对于此的东西。我不确定这是否真的有意义,不承认我需要帮助大声笑。祝大家感恩节快乐,我怀疑今天有人在使用stackoverflow。

1 个答案:

答案 0 :(得分:1)

嗯......你真的不需要匹配球员和球队。

让我们从后端(数据)角度思考:

您有玩家模型和团队模型 球员属于球队,球队有很多球员。为了找到一个玩家属于哪个团队,我们所要做的就是将一个外键:team_id添加到玩家模型中:

team_id,是团队的ID。通常你不想使用名字,因为:1。它可能会改变,你不想在更改团队名称时更新所有玩家。 2,效率不高。 (字符串字段与整数字段)ID始终是唯一的,您永远不应该更改它们。

让我们说你有科比和湖人队

//here's Kobe
var kobe = {
  id: 24,  //yea, all models should have their own primary key - id
  name: 'Kobe',
  team_id: 3
}

//this is Lakers in the database
var lakers = {
  id: 3,  //id for lakers,
  name: 'Lakers'
}

现在,您如何找到科比所属团队的名称?

让我们说,你有一组球队(所有球队)

var teams = new Teams([ ..all the teams! .. ]);

//to find the name of the team

teams.get(kobe.get('team_id')).get('name');  // you find the model first, then read its name.

你可以将球员包裹在球队内,或者将球队分配给球员,但你不必这样做。这实际上取决于你的应用程序的主要目的。(或视图)在一些大型应用程序中,你可能会找到人们将团队包装到玩家实例的地方,以及玩家被团队包裹的其他地方;

在您的情况下,您似乎尚未决定如何处理您的观点。并且,将两个集合传递到一个视图中没有错(但是当你必须这样做时,通常意味着你需要重新考虑如何组织你的页面)

PlayersView = Backbone.View.extend({

  initialize: function(options) {
    //in case teams/players is not passed to the view, we just set them to empty collections
    this.teams = options.teams || new Teams([]);
    this.players = options.players || new Players([]);
  }

});

实例化视图时,请传递两个集合:

var playersView = new PlayersView({
  players: players,
  teams: teams
});

并在您的模板中,如果您只是列出所有玩家:

<% _.each(players, function(player) {
   <% var team = teams.get(player.get('team_id'))%>
   <%= player.get('name') %> belongs to <%= team.get('name') %>
}) { %>

或者如果您要列出球队及其球员: //在这种情况下,你真的应该创建子视图而不是在一个模板中完成所有视图

<% _.each(teams, function(team) {
   <ul class="<%= team.get('name')%>">
     <% var teamPlayers = players.where({team_id: team.get('id')}) %>
         <% _.each(teamPlayers, function(player) {
           <li>
             <%= player.get('name') %> belongs to <%= team.get('name') %>
           </li>
         <% }) %>
   </ul>
}) { %>

=================

修改

在您的代码中

  

_。each(this.collection.where({team:“lakers”}),function(model){          var playerView = new PlayerView({model:model});          这$ el.append(playerView.render()EL);          此$ el.addClass( '湖人')。 },这);

你在_.each()中重复addClass,这是不必要的。因为你已经决定要找到湖人队员,所以你应该在模板中进行,或者只是将其作为根元素的className分配,假设每个团队都在视图中:

 //this is a view for a Team, it's model should be Team
 TeamView = Backbone.View.extend({
   className: function() {
     return this.model.get('name');
   }
 });