Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8502679
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T01:33:08+00:00 2026-06-11T01:33:08+00:00

I have a Backbone collection with a load of models. Whenever a specific attribute

  • 0

I have a Backbone collection with a load of models.

Whenever a specific attribute is set on a model and it is saved, a load of calculations fire off and the UI rerenders.

But, I want to be able to set attributes on several models at once and only do the saving and rerendering once they are all set. Of course I don’t want to make several http requests for one operation and definitely dont want to have to rerender the interface ten times.

I was hoping to find a save method on Backbone.Collection that would work out which models hasChanged(), whack them together as json and send off to the back end. The rerendering could then be triggered by an event on the collection. No such luck.

This seems like a pretty common requirement, so am wondering why Backbone doesn’t implement. Does this go against a RESTful architecture, to save several things to a single endpoint? If so, so what? There’s no way it’s practical to make 1000 requests to persist 1000 small items.

So, is the only solution to augment Backbone.Collection with my own save method that iterates over all its models and builds up the json for all the ones that have changed and sends that off to the back end? or does anyone have a neater solution (or am I just missing something!)?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T01:33:09+00:00Added an answer on June 11, 2026 at 1:33 am

    I have ended up augmenting Backbone.Collection with a couple of methods to handle this.

    The saveChangeMethod creates a dummy model to be passed to Backbone.sync. All backbone’s sync method needs from a model is its url property and toJSON method, so we can easily knock this up.

    Internally, a model’s toJSON method only returns a copy of it’s attributes (to be sent to the server), so we can happily just use a toJSON method that just returns the array of models. Backbone.sync stringifies this, which gives us just the attribute data.

    On success, saveChanged fires off events on the collection to be handled once. Have chucked in a bit of code that gets it firing specific events once for each of the attributes that have changed in any of the batch’s models.

    Backbone.Collection.prototype.saveChanged = function () {
        var me = this,
            changed = me.getChanged(),
            dummy = {
                url: this.url,
                toJSON: function () {
                    return changed.models;
                }
            },
            options = {
                success: function (model, resp, xhr) {
                    for (var i = 0; i < changed.models.length; i++) {
                        changed.models[i].chnageSilently();
                    }
                    for (var attr in changed.attributes) {
                        me.trigger("batchchange:" + attr);
                    }
                    me.trigger("batchsync", changed);
                }
            };
        return Backbone.sync("update", dummy, options);
    }
    

    We then just need the getChanged() method on a collection. This returns an object with 2 properties, an array of the changed models and an object flagging which attributes have changed:

    Backbone.Collection.prototype.getChanged = function () {
        var models = [],
            changedAttributes = {};
        for (var i = 0; i < this.models.length; i++) {
            if (this.models[i].hasChanged()) {
                _.extend(changedAttributes, this.models[i].changedAttributes());
                models.push(this.models[i]);
            }
        }
        return models.length ? {models: models, attributes: changedAttributes} : null;
    }
    

    Although this is slight abuse of the intended use of backbones ‘changed model’ paradigm, the whole point of batching is that we don’t want anything to happen (i.e. any events to fire off) when a model is changed.

    We therefore have to pass {silent: true} to the model’s set() method, so it makes sense to use backbone’s hasChanged() to flag models waiting to be saved. Of course this would be problematic if you were changing models silently for other purposes – collection.saveChanged() would save these too, so it is worth considering setting an alternative flag.

    In any case, if we are doing this way, when saving, we need to make sure backbone now thinks the models haven’t changed (without triggering their change events), so we need to manually manipulate the model as if it hadn’t been changed. The saveChanged() method iterates over our changed models and calls this changeSilently() method on the model, which is basically just Backbone’s model.change() method without the triggers:

    Backbone.Model.prototype.changeSilently = function () {
        var options = {},
        changing = this._changing;
        this._changing = true;
        for (var attr in this._silent) this._pending[attr] = true;
        this._silent = {};
        if (changing) return this;
    
        while (!_.isEmpty(this._pending)) {
            this._pending = {};
            for (var attr in this.changed) {
            if (this._pending[attr] || this._silent[attr]) continue;
            delete this.changed[attr];
            }
            this._previousAttributes = _.clone(this.attributes);
        }
        this._changing = false;
        return this;
    }
    

    Usage:

    model1.set({key: value}, {silent: true});
    model2.set({key: value}, {silent: true});
    model3.set({key: value}, {silent: true});
    collection.saveChanged();
    

    RE. RESTfulness.. It’s not quite right to do a PUT to the collection’s endpoint to change ‘some’ of its records. Technically a PUT should replace the entire collection, though until my application ever actually needs to replace an entire collection, I am happy to take the pragmatic approach.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a Backbone collection model (with sub-models as elements) and views to edit
I have a Backbone collection jQuery -> class App.Collections.List extends Backbone.Collection model: App.Models.ListItem I
I have a Backbone View that has a Collection as its Model. If the
I use backbone.js and have a model without a collection. In the view I
I have the following Backbone.js model and collection: // Model lr.Event = Backbone.Model.extend({}); //
I have very simple backbone model and collection. I have a corresponding backbone.marionette.CollectionView and
My Backbone Collection receives 30 models on fetch(). I have tried newColl=origColl.first(2); to return
I have a Backbone collection and when I add a new model to it
I have a backbone collection and when I remove a model from the collection,
I have a backbone collection which has a bunch of models with date attributes

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.