Backbone.js: Load multiple collections with one request

断了今生、忘了曾经 提交于 2020-01-14 04:04:09

问题


At this time my code fetches each collection separately but given that the same requests are made together I would like it to load the collections in one request.

This is what my request response would look like if I were to merge all:

[{id: 5, milestoneName: 'some milestone', tasks: [{id: 1, taskName: 'first task', dueDate: 'Jan 15'}, {id: 2, taskName: 'second task', dueDate: ''}]},{id: 6, milestoneName: 'some other milestone', tasks: [{id: 3, taskName: 'third task', dueDate: 'Jan 16'}, {id: 4, taskName: 'fourth task', dueDate: ''}]}]  

Basically, there are milestones that contain tasks. At this point the milestone collection fetches the milestones and when they are fetched, the task collection(of each milestone) is initialized and fetches the tasks. This can take quite a while (2-3 seconds, that are obvious). If I could load them in one request everything would work faster.

milestoneModel = Backbone.Model.extend({});

milestoneCollection = Backbone.Collection.extend({
  url: 'http://some-url',
  model: milestoneModel
});

taskModel = Backbone.Model.extend();

taskCollection = Backbone.Collection.extend({
  url: 'http://task-url',
  model: taskModel
});

I would like the taskCollection to be part of the each milestoneModel and to be reset as soon as this request response arrives.


回答1:


Ah. Nested models and fetching it all. :-) Basically, have your server send exactly what you're sending. Your JSON structure of the nested tasks collections are fine as is. Here is what you do.

In your Milestone Model, you modify the parse to look for the property tasks then you process it accordingly. For example:

parse: function(response) {
    if (_.has(response, 'tasks')) {
        if (this.tasks) {  // Check if this model has a tasks collection already defined
            this.tasks.reset(response.tasks); // It does, so reset it with data
        } else {
            this.tasks = new taskCollection(response.tasks); // It doesn't, so create one
        }
        delete response.tasks;
        // Don't forget to delete tasks from response or it will be passed onto the model
        // set and appear in your attributes
    }
    return response;  // Do pass on all the other attributes that belong to the model
}

This assumes you want the taskCollection as a property of your Milestone model and not an attribute. It basically checks if a tasks array is present as a property of the response, if there is one, we check the model object if it has the tasks collection already defined. If it does, reset the collection with the data. If not, create the collection with data.

One more thing. I'm not sure if you have to do this or not. But I think when you fetch() your Milestones collection, you might have to pass an option parse:true. I kind of forget when you need to do this, or if this a relic from a previous Backbone. Try placing a console.log() in your parse to check if your Milestone model is properly parsing the response. If it isn't, then try passing the parse:true option.



来源:https://stackoverflow.com/questions/12296221/backbone-js-load-multiple-collections-with-one-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!