骨干数据映射

时间:2012-08-02 15:17:39

标签: javascript model-view-controller backbone.js datamapper

为了将我的骨干模型映射到我从服务器获得的内容,我使用的是GroupOn Dev博客中描述的技术:https://engineering.groupon.com/2012/javascript/extending-backbone-js-to-map-rough-api-responses-into-beautiful-client-side-models/

但是,这仅将传入数据映射到模型。

我希望这两种方式,所以当我保存模型时,它会准备模型属性以匹配服务器模型。

准备模型输出的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,我的服务器响应与我发布的完全不同。我在Backbone.sync对象的机制中发现了一种方法,我可以在Backbone.sync中的以下语句中向我的服务器发布一个自定义JSON对象:

if (!options.data && model && (method == 'create' || method == 'update')) {
  params.contentType = 'application/json';
  params.data = JSON.stringify(model.toJSON());
}

同步评估options.data是否不存在然后将params.data设置为字符串化模型。 options.data检查将我锁定。如果存在,则sync将使用该而不是模型。因此,鉴于此,我覆盖了我的model.save,因此可以传入我的服务器所期望的属性哈希。

以下是我如何覆盖它:

save : function(key, value, options) {
    var attributes = {}, opts = {};

    //Need to use the same conditional that Backbone is using
    //in its default save so that attributes and options
    //are properly passed on to the prototype
    if (_.isObject(key) || key == null) {
        attributes = key;
        opts = value;
    } else {
        attributes = {};
        attributes[key] = value;
        opts = options;
    }

    //In order to set .data to be used by Backbone.sync
    //both opts and attributes must be defined
    if (opts && attributes) {
        opts.data = JSON.stringify(attributes);
        opts.contentType = "application/json";
    }

    //Finally, make a call to the default save now that we've
    //got all the details worked out.
    return Backbone.Model.prototype.save.call(this, attributes, opts);
}

那么你如何在你的情况下使用它?基本上你要做的是创建一个方法来反转映射并返回结果JSON。然后,您可以按如下方式从视图或控制器中调用save:

getReversedMapping : function() {
    ver reversedMap = {};
    ...
    return reversedMap;
},
saveToServer : function() {
    this._model.save(this.getReverseMapping, {
        success : function(model, response) {
            ...
        },
        error : function(model, response) {
            ...
        }
    })
}

由于被覆盖的保存会自动将您传入的JSON复制到options.data,Backbone.sync将使用它来发布。

答案 1 :(得分:0)

Brendan Delumpa 的答案有效,但它使事情过于复杂。

请勿在保存方法中执行此操作。您不希望每次都复制这些参数检查(如果它们在Backbone中以某种方式改变了怎么办?)。

而是覆盖模型中的sync方法,如下所示:

var MyModel = Backbone.Model.extend({
    ...,
    sync: function (method, model, options) {
        if (method === 'create' || method === 'update') {

            // get data from model, manipulate and store in "data" variable
            // ...

            options.data = JSON.stringify(data);
            options.contentType = 'application/json';
        }

        return Backbone.Model.prototype.sync.apply(this, arguments);
    }
});

当您需要以服务器就绪格式“准备”数据时,就可以了。