6

我正在创建一个连接到 RESTful 后端的主干应用程序。当我在模型上调用 save() 时,它将发布数据作为字符串化 JSON 发送:

{"firstName":"first","lastName":"last","Email":"email@gmail.com"}

但我的服务器希望它像查询字符串一样格式化:

firstName=first&lastName=last&Email=email@gmail.com

有没有办法让主干以不同的方式发送它?

4

6 回答 6

8

Backbone 没有提供任何开箱即用的东西。
但是很容易根据您的需要覆盖和定制它。

看看源代码: http ://documentcloud.github.com/backbone/docs/backbone.html

并检查 call save,它将sync在后台触发呼叫。

所以你需要的是Backbone.sync用你自己的覆盖函数。

我会修改以下部分:

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

if (!options.data && model && (method == 'create' || method == 'update')) {
      params.contentType = 'application/json';
      params.data = $.param(model); // <-- CHANGED 
}

注意我正在使用jQuery 参数

如果您想使用自定义函数,请检查以下问题: Javascript 对象的查询字符串编码

[更新]
无需直接修改。最好用您自己的函数“Backbone.sync”覆盖它检查主干存储库的“TODO”示例。它有一个localStorage.js覆盖 Backbone.sync 函数的文件https://github.com/documentcloud/backbone/tree/master/examples

于 2012-07-10T19:47:49.387 回答
2

我在工作中遇到了这个问题,Backbone.emulateJSON 也对我不起作用。在一些帮助下,我能够想出这个解决方法。我们覆盖 Backbone.ajax 函数并将 contentType 更改为“application/x-www-form-urlencoded”并使用 $.param 正确序列化数据。

Backbone.ajax = function() {
    if(arguments[0].data && arguments[0].contentType == "application/json"){
        arguments[0].data = $.param(JSON.parse(arguments[0].data));
        arguments[0].contentType = "application/x-www-form-urlencoded";
    }
    return Backbone.$.ajax.apply(Backbone.$, arguments);
}
于 2013-11-18T22:37:42.787 回答
0

Backbone.sync 使用jQuery.ajax函数,因此我们可以修改 jqXHR 或发送到服务器的数据(通过 beforeSend)。

var oldSync = Backbone.Model.prototype.sync;
var SomeModel = Backbone.Model.extend({
    url: 'test.json',

    defaults: {
        id: 1,
        foo: 'test'
    },

    sync: function (method, model, options) {
        // options are passed to the jQuery.ajax
        _.extend(options, {
            emulateHTTP: true,
            emulateJSON: false,
            beforeSend: function(xhr, settings) {
                // settings.data is a body of our request.
                if (_.isString(settings.data)) {
                    // settings.data is a JSON-string like '{"id":1, "foo":"test"}'
                    settings.data = Backbone.$.parseJSON(settings.data);
                }

                settings.data = Backbone.$.param(settings.data);
                // settings.data is 'id=1&foo=test'
            }
        });

        oldSync.apply(this, arguments);
    }
});

var model = new SomeModel();
model.save();

实际上我们可以创建一个mixin!:)

于 2014-09-17T13:33:43.233 回答
0

我通过覆盖模型的同步功能来做到这一点:

var MyModel = Backbone.Model.extend({ 
    "sync": function(method, model, options) {
        if (method == "update" || method == "create") {
            options = options ? _.clone(options) : {};
            options['data'] = $.param(this['attributes']);
        }
        var arguments = [method, model, options];
        return Backbone.sync.apply(this, arguments);
    }
});
于 2013-03-14T11:47:30.580 回答
0

也许这可以帮助你,试试: http ://backbonejs.org/#Sync-emulateJSON

于 2012-07-10T15:44:26.297 回答
0

我找到解决方案,请参阅:

  1. 我用

    Backbone.emulateJSON = true;

  2. 我写了“更新”案例:

    options.url = "/user/"+Math.random(1, 1000);
    options.type = "POST";
    //.1/2 WORK
    //options.data = (model instanceof Backbone.Model)?model.toJSON():{};
    options.data = model.toJSON();
    break;
    
于 2013-05-17T15:39:13.240 回答