Save several Backbone models at once

后端 未结 3 1939
情歌与酒
情歌与酒 2021-02-06 00:44

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

3条回答
  •  北海茫月
    2021-02-06 01:32

    This is what i came up with.

    Backbone.Collection.extend({
        saveAll: function(models, key, val, options) {
    
            var attrs, xhr, wait, that = this;
    
            var transport = {
                url: this.url,
                models: [],
                toJSON: function () {
                    return { models: this.models };
                },
                trigger: function(){
                    return that.trigger.apply(that, arguments);
                }
            };
    
            if(models == null){
                models = this.models;
            }
    
            // Handle both `"key", value` and `{key: value}` -style arguments.
            if (key == null || typeof key === 'object') {
                attrs = key;
                options = val;
            } else {
                (attrs = {})[key] = val;
            }
    
            options = _.extend({validate: true}, options);
            wait = options.wait;
    
            // After a successful server-side save, the client is (optionally)
            // updated with the server-side state.
            if (options.parse === void 0) options.parse = true;
    
            var triggers = [];
    
            _.each(models, function(model){
    
                var attributes = model.attributes;
    
                // If we're not waiting and attributes exist, save acts as
                // `set(attr).save(null, opts)` with validation. Otherwise, check if
                // the model will be valid when the attributes, if any, are set.
                if (attrs && !wait) {
                    if (!model.set(attrs, options)) return false;
                } else {
                    if (!model._validate(attrs, options)) return false;
                }
    
                // Set temporary attributes if `{wait: true}`.
                if (attrs && wait) {
                    model.attributes = _.extend({}, attributes, attrs);
                }
    
                transport.models.push(model.toJSON());
    
                triggers.push(function(resp){
                    if(resp.errors){
                        model.trigger('error', model, resp, options);
                    } else {
                        // Ensure attributes are restored during synchronous saves.
                        model.attributes = attributes;
                        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
                        if (wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
                        if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
                            return false;
                        }
                        model.trigger('sync', model, resp, options);
                    }
                });
    
                // Restore attributes.
                if (attrs && wait) model.attributes = attributes;
            });
    
            var success = options.success;
            options.success = function(resp) {
                _.each(triggers, function(trigger, i){
                    trigger.call(options.context, resp[i]);
                });
                if (success) success.call(options.context, models, resp, options);
            };
            return this.sync('create', transport, options);
        }
    });
    

提交回复
热议问题