Backbone Collections - 收集级别的Union Two Collections

时间:2014-12-03 15:17:13

标签: javascript backbone.js underscore.js backbone-collections

我的示例应用程序中有两个单独的集合。我想要做的是通过userId联合集合。我过去通常在渲染级别处理过这个问题,但是我真的很想在收集级别解析数据并且渲染为“愚蠢的”#34;如果你愿意,可以简单地将数据传递给我的下划线模板。

我遇到了一些线索,但这些线程得到了解答,但我无法在收集级别完成此任务。

我在这里设立了一名侦探来更好地描述情况。 http://plnkr.co/edit/UCAFycdmsLaD14cYgTdZ?p=preview

首先,我对用户集合进行抓取,以获取所有userId和要解析的锻炼集合信息。

users.json

[
    {
        "user" : 53,
        "firstname" : "Todd",
        "lastname" : "Jones",
        "email" : "xxx@gmail.com",
        "avatar" : ""
    },
    {
        "user" : 53,
        "firstname" : "Sarah",
        "lastname" : "Thomas",
        "email" : "xxx@gmail.com",
        "avatar" : ""
    }
]       

tracker.json

[
    {
        "user" : 53,
        "distance" : 3,
        "duration" : 180000,
        "date" : "November 27, 2014 09:45:00",
        "felt" : "Tired at first"
    },
    {
        "user" : 53,
        "distance" : 3.256,
        "duration" : 978600,
        "date" : "November 28, 2014 10:15:00",
        "felt" : "Great"
    }
]       

我在这个帖子How do I union/merge two Collections by their 'id' using UnderscoreJS

中看到了一些例子

但是我相信我的问题是我试图错误地访问WorkoutCollection中的UserCollection,或者我还没有将它解析为JSON对象(这发生在渲染函数中)。

整个代码位于下方,plunker位于http://plnkr.co/edit/UCAFycdmsLaD14cYgTdZ?p=preview

提前感谢任何见解。

// Users Model
var Users = Backbone.Model.extend({

    defaults: function() {
        return {
            avatar: "" // generic Avatar if none supplied by users
        };
    }

});

// Workouts Collection
var UserCollection = Backbone.Collection.extend({

    model : Users,
    url: '/data/users.json',
    parse: function (responses) {
        return responses;
    }

});
// Workouts Model
var Workouts = Backbone.Model.extend({

    defaults: function() {
        return {
            felt: "Good"
        };
    },

});

// Workouts Collection
var WorkoutCollection = Backbone.Collection.extend({

    model : Workouts,
    url: '/data/tracker.json',
    parse: function (responses) {

        var data = [];
        _.each(responses, function(response){

            // format durations
            var x = response.duration;
            var d = moment.duration(x, 'milliseconds');
            var hours = Math.floor(d.asHours());
            var mins = Math.floor(d.asMinutes()) - hours * 60;
            var seconds = Math.floor(d.asSeconds()) - mins * 60;
            var duration = "";

            if (hours > 0) {
                duration += hours + " hours ";
            }

            if (mins > 0) {
                duration += mins + " minutes ";
            }

            if (seconds > 0) {
                duration += seconds + " seconds ";
            }

            response.duration = duration;

            // format workout dates
            var y = response.date;
            var z = moment(y).format('dddd, MMM Do YYYY');

            response.date = z;
        });

        var result = [];
        _.each(responses, function(el){
            console.log(el)
            console.log(UserCollection.get("user"))
            _.extend(el,_.where(UserCollection, {user: el.user})[0] || {});
            result.push(el);
        });

        console.log(result);

      return responses;
    }
});

// Main
var ExerciseApp = Backbone.View.extend({

    el: "#exercise_app",
    template: null,

    initialize: function() {

        this.userCollection = new UserCollection();
        this.listenTo(this.userCollection, "reset sync remove", this.usersLoaded);
        this.userCollection.fetch({dataType: "json"});

    },

    usersLoaded: function() {

        this.workoutCollection = new WorkoutCollection();
        this.listenTo(this.workoutCollection, "reset sync remove", this.render);
        this.workoutCollection.fetch({dataType: "json"});
        this.template = _.template($('#workout-table-template').html());

    },

    render: function() {

        var workouts = this.workoutCollection.toJSON();
        var users = this.userCollection.toJSON();
        this.$el.html(this.template({workouts: workouts, users: users}));

    },

});

$(document).ready(function() {
    var app = new ExerciseApp
});

1 个答案:

答案 0 :(得分:0)

我现在按照我喜欢的方式工作。

我最终做的是将用户集合传递给锻炼集合。

然后,我可以轻松地使用下划线_map函数合并数据。

usersLoaded: function() {

    var users = this.userCollection.toJSON();
    this.workoutCollection = new WorkoutCollection(users);
    this.listenTo(this.workoutCollection, "reset sync remove", this.render);
    this.workoutCollection.fetch({dataType: "json"});
    this.template = _.template($('#workout-table-template').html());

},

parse: function (responses) {

    var workouts = responses;
    var users = this.users;

    var mergedCollection = _.map(users, function (user) {  
        var workout = _.find(workouts, function (o) { 
            return o.userId == user.userId;
        }); 
        return _.extend(user, workout); 
    });


    _.each(mergedCollection, function(response){

        // format durations
        var x = response.duration;
        var d = moment.duration(x, 'milliseconds');
        var hours = Math.floor(d.asHours());
        var mins = Math.floor(d.asMinutes()) - hours * 60;
        var seconds = Math.floor(d.asSeconds()) - mins * 60;
        var duration = "";

        if (hours > 0) {
            duration += hours + " hours ";
        }

        if (mins > 0) {
            duration += mins + " minutes ";
        }

        if (seconds > 0) {
            duration += seconds + " seconds ";
        }

        response.duration = duration;

        // format workout dates
        var y = response.date;
        var z = moment(y).format('dddd, MMM Do YYYY');

        response.date = z;
    });

  return mergedCollection;
}