javascript – 一次保存几个主干模型

前端之家收集整理的这篇文章主要介绍了javascript – 一次保存几个主干模型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个负载模型的骨干集合.

无论何时在模型上设置了一个特定的属性,并且它被保存,计算的负载将被消除,并且UI重新上弹.

但是,我想要能够一次设置几个模型的属性,只有一旦设置完毕,才能进行保存和重新登录.当然,我不想为一个操作提供几个http请求,绝对不需要重新使用十次接口.

我希望在Backbone.Collection上找到一个保存方法,该方法可以计算出哪些模型hasChanged(),将它们一起作为json发送到后端.然后可以通过集合上的事件来触发重画.没有这样的运气.

这似乎是一个很常见的要求,所以我想知道为什么Backbone没有实现.这是否符合RESTful架构,可以将多项功能保存到单个端点?如果是这样,那么什么?让1000个请求持续1000个小项目是没有办法的.

所以,是唯一的解决方案来增加Backbone.Collection与我自己的保存方法,迭代所有的模型,并建立所有的更改的json,并发送到后端?或者有人有一个更整洁的解决方案(或者我只是错过了一些东西!)?

解决方法

我已经结束了扩展Backbone.Collection与一些方法来处理这个.

saveChangeMethod创建一个要传递给Backbone.sync的虚拟模型.所有骨干的同步方法需要一个模型就是它的url属性和toJSON方法,所以我们可以很容易的敲出来.

在内部,模型的toJSON方法只返回一个属性的副本(要发送到服务器),所以我们可以很高兴地使用一个只返回模型数组的toJSON方法. Backbone.sync将这个字符串化,这给了我们只是属性数据.

一旦成功,saveChanged就会关闭事件的集合,以处理一次.已经吸入了一些代码,它可以为任何批次的模型中的每个属性触发特定事件一次.

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);
}

然后我们需要一个集合的getChanged()方法.这将返回一个具有2个属性的对象,一个更改模型的数组和一个对象标记哪些属性已更改:

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;
}

虽然这是轻微滥用骨干改变模式的范例的预期用途,但是批量的全部要点是,当模型改变时,我们不希望任何事情发生(即任何事件都要触发).

因此,我们必须将{silent:true}传递给模型的set()方法,所以使用骨干的hasChanged()来标记等待保存的模型是有意义的.当然,如果您为了其他目的而以静默方式更改模型,那么这将是一个问题. – collection.saveChanged()将保存这些,所以值得考虑设置一个替代标志.

无论如何,如果我们这样做,当保存时,我们需要确保骨干网现在认为模型没有改变(没有触发他们的改变事件),所以我们需要手动操作模型,就好像它没有被改变了saveChanged()方法迭代我们改变的模型,并在模型上调用这个changeSilently()方法,这基本上只是Backbone的没有触发器的model.change()方法

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;
}

用法

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

回覆. RESTfulness ..对集合的端点进行PUT更改其“某些”记录是不正确的.技术上,PUT应该替代整个集合,尽管直到我的应用程序实际上需要替换整个集合,我很高兴采取务实的方法.

猜你在找的JavaScript相关文章