为服务器请求字符串化对象的一部分

stringify part of an object for server request

我正在重写 Backbone 集合的 fetch 方法以在某些情况下向不同的 url 发送请求,并且我必须用它发送一些数据。新的 fetch 方法(从另一个 SO 答案复制而来)看起来像这样

fetch(options){

    if(options && options.data){
         options = _.extend({url : '/someendpoint/'}, options || {});
     }

    return Backbone.Collection.prototype.fetch.call(this, options);
}

当我在视图中调用 fetch 方法时,我向它传递了一些数据(随 fetch 中的选项参数一起提供)

 callFetchMethod(){

   var min = $("#min").val();
   var max = $("#max").val();
   var range = {};
   range['min'] = min;
   range['max'] = max;
   mycollection.fetch({'data': range}); //send the object with min and max to collection
  }

问题是服务器无法识别数据对象。我试过在将它发送到集合之前调用 JSON.stringify(range) 并在集合内部调用 JSON.stringify(options.data) ,但都无济于事。

我需要使用一个新的url并且我需要向服务器发送数据。上面的fetch方法怎么实现呢?

更新: 这是在对整个选项对象或只是 options.data

进行字符串化的各种尝试中发生的情况

如果我像这样将整个选项对象字符串化

如果(选项 && options.data){ 选项 = _.extend({url: '/someendpoint'}, 选项 || {}); options.data = JSON.stringify(选项); console.log(选项,"options in collection"); }

没有数据发送到服务器(并且没有调用正确的 url)

{"url":"/someendpoint","data":"{\"min\":\"1429740602093\",\"max\":\"1429740602093\"}"}

如果我像这样对 options.data 进行字符串化

if (options && options.data){
            options = _.extend({url: '/someendpoint'}, options || {});
            options.data = JSON.stringify(options.data);
            console.log(options, "options in collection");
        }

这是控制台输出

Object {url: "/someendpoint", data: "{"min":"1429740602093","max":"1429740602093"}"} "options in collection"

我在服务器上收到一条错误消息

the server throws an unexpected end of JSON input error

因此,Backbone.Collection.fetch 正在调用 Collection.sync('read', this, options),其中 'read' 是 HTTP 请求方法。根据 Docs this translates to an HTTP GET. And we know 规范,GET 请求应忽略所有数据负载。

所以...,我们要么必须将 range 数据附加到 url,要么改用 POST 请求。

设置您的 url 参数以获取

动态设置集合 url 非常简单。在你的例子中,你可以这样做,

callFetchMethod(){
   // assume mycollection already instantiatied
   var min = $("#min").val();
   var max = $("#max").val();
   mycollection.url = '/someendpoint?max=' + max '&min=' + min;
   mycollection.fetch(); // The url is already set
}

使用POST获取

基于此 Answer,我们可以通过提供 type 属性 来覆盖 POST 获取请求。所以,我们的新 callFetchMethod 看起来像:

callFetchMethod(){
   // assume mycollection already instantiatied
   var min = $("#min").val();
   var max = $("#max").val();
   var range = {};
   range['min'] = min;
   range['max'] = max;
   mycollection.fetch({type: 'POST', data: JSON.stringify(range)});
}

这应该有效,因为 Backbone 正在做的是:

var xhr = options.xhr = Backbone.ajax(_.extend(params, options));

同时,params 有一个 type 属性 被 Collection.fetch() 设置为 GET_.extend()type 属性 来自 options,并提供 data 属性 到 Backbone.ajax()(顺便说一句,它只是一个薄包装$.ajax).

注:

This code is untested, please let me know if you run into any issues