组织backbone.js集合?

时间:2013-12-11 16:58:57

标签: javascript json backbone.js

如何创建由id组织的集合(在backbone.js中)。例如,我认为集合需要按日期,类别,关键字,列表的类型进行组织是很常见的。在我的情况下,我试图找到一种优雅的方式来组织球员到球队。

我不认为我需要一个插件,我的目标只是组织玩家在div中分组,同时使用一个干净的json文件,这样我就可以有一个很好的组织列表。理想情况下,为此使用一个json文件会很好,并且构建HTML类似于json本身在嵌套方面的结构,在我的示例中league是所有内容的父级,然后是{{1} }是team的父级。

我多次经历过许多骨干教程,并且非常舒服地理解流程和语法,但所有教程都使用一个集合输出一个没有特定顺序的简单列表。

基本上我希望能够创建一个干净的json数组,如下所示。然后将其转换为组织良好的HTML。

players

所以这个json结构是有效的,但它不是我已经使用它的嵌套了一点,所以访问模型需要一些不同的技术,我希望了解这种数组是否理想?如果是这样的话,我如何分组{ "league": [{ "team":"Lakers", "players": [ { "name": "Kobe" }, { "name": "Steve" } ] }, { "team":"Heat", "players": [ { "name": "LeBron" }, { "name": "Mario" } ] }] } Kobe在一个div中,可能是类名Steve,同时显然将它与LakersLeBron区分开来div中的两个也可能是一类Mario

我可以使用的另一个例子就像演员到电影收藏,再次是json格式理想(对我而言)在这里我显然将演员分组到他们受人尊敬的电影中?我非常感谢有关使用模板或模板构建一个干净的视图或视图的一些提示,以便输出这个漂亮而整洁。

Heat

再次使用这个json数据和backbone.js如何为这个数组创建一个可维护的视图?

最后注意事项我能够使用两个json文件成功将玩家分组到团队,并分配一个与团队ID匹配的玩家和ID,然后使用玩家集合将团队集合循环使用{ "movies": [{ "title":"Prisoners", "actors": [ { "name": "Hugh Jackman" }, { "name": "Jake Gyllenhaal" } ] }, { "title":"Elysium", "actors": [ { "name": "Matt Damon" }, { "name": "Jodie Foster" } ] }] } 组织它(我试图更好地重新思考)。对我而言,这不是利用骨干,它可能会让人感到困惑,对我来说似乎不对。所以我希望在这里提高我的知识并变得更好。我非常欣赏清晰简洁的信息,我真的很难围绕这个话题:)

谢谢!

2 个答案:

答案 0 :(得分:3)

将您的JSON保持在Backbone友好结构中,这意味着您的模型在放入集合后很容易组织。

JSON示例

[
    { league : 1, team : 'lakers', player : 'kobe' }
    { league : 1, team : 'lakers', player : 'steve' }
    // And so on
]

考虑到大多数骨干集合是通过RESTful JSON api构建的,这很容易直接获取到集合中然后进行排序。每次将模型添加到集合中时,或者当您要求模型运行时,都会运行集合上的comparator()函数。

主干收集示例

var Players = Backbone.Collection.extend({

    initialize : function() {
        // Grab the JSON from the API
        // this.fetching is now a deferred object
        this.fetching = this.fetch();
    }

    // Comparator example one, as a string
    comparator : 'team',

    // Comparator example two, as a function
    comparator : function(model) {
        return model.get('team');
    }

});

作为函数方法的比较器显然更适合更复杂的排序算法,否则比较器作为字符串方法会更好。请记住函数方法虽然可以返回一个字符串(例如上面),-11将是更好的返回值,以指示它的排序位置。

模型比较的比较示例

comparator : function(modelA, modelB) {
     var teamA = modelA.get('team'),
         playerA = modelA.get('player'),
         teamB = modelB.get('team'),
         playerB = modelB.get('player');

     if (teamA < teamB) { // string comparison
         return 1;
     } else if (playerA < playerB} {
         return 1;
     } else {
         return -1;
     }
}

现在每当模型被添加到集合中时,如果使用最后一个示例,按团队然后按玩家名称,则将其分类到正确的位置。

使用集合的简单视图示例

var ViewExample = Backbone.View.extend({

    el : "#example-container",

    render : function() {

        var self = this;

        // Use the deffered object to make sure models are
        // all available in the collection before we render
        this.collection.fetching.done(function() {

            self.collection.each(function(model) {

                self.$el.append('<p>' + model.get('player') + '</p>');

            });

        });

        return this;
    }
});

// Create the view and pass in the collection
// that will immediately fetch it's models
var view = new ViewExample({
    collection : new Players()
});

这里的代码未经测试

答案 1 :(得分:2)

首先构建数据的工作模型。您的JSON建议了一个层次结构:一组每个都有一组玩家的团队。这是一个可能的实现:

var Player = Backbone.Model.extend();
var Players = Backbone.Collection.extend({
    model: Player
});
var Team = Backbone.Model.extend({
    constructor: function(data, opts) {
        // I like my subcollections as attributes of the model
        // and not on the settable properties
        this.players = new Players();

        Backbone.Model.call(this, data, _.extend(opts, {parse: true}));
    },
    parse: function(data) {
        // Players are handled in a subcollection
        if (_.isArray(data.players))
            this.players.reset(data.players);

        // They are removed from the model properties
        return _.omit(data, 'players');
    }
});
var Teams = Backbone.Collection.extend({
    model: Team,
    parse: function(resp) {
        return resp.league;
    }
});

现在您可以创建根集合。请注意,您也可以fetch而不是使用数据对其进行实例化。

// teams list
var teams = new Teams(data, {parse: true});

// for example, to get all players in all teams
var allplayers = _.flatten(teams.map(function(team) {
    return team.players.models;
}));
console.log(_.invoke(allplayers, 'get', 'name'));

演示:http://jsfiddle.net/8VpFs/

一旦你的结构到位,你可以担心渲染它。我们假设你有这个(下划线)模板

<ul>
  <% _(teams).each(function(team) { %>
      <li><strong><%= team.team %></strong>
        <ul>
          <% _(team.players).each(function(player) { %>
              <li><%= player.name %></li>
          <% }); %>
        </ul>
    </li>
  <% }); %>
</ul>

您可以更改Team模型以输出模型的序列化表示形式:

var Team = Backbone.Model.extend({
    // ... as before

    toJSON: function() {
        var json = Backbone.Model.prototype.toJSON.call(this);
        json.players = this.players.toJSON();
        return json;
    }
});

并渲染您的模板

var tpl = _.template($('#tpl').html());
var html = tpl({
    teams: teams.toJSON()
})
$('body').append(html);

这通常会进入视野。

http://jsfiddle.net/8VpFs/1/

使用fetch

var teams = new Teams();
teams.fetch().then(function() {
    var tpl = _.template($('#tpl').html());
    var html = tpl({
        teams: teams.toJSON()
    });
    $('body').append(html);
});

http://jsfiddle.net/8VpFs/2/