我正在重写 Backbone Collection 的 fetch 方法,以便在某些情况下将请求发送到不同的 url,并且我必须使用它发送一些数据。新的获取方法(从另一个SO答案复制)看起来像这样
fetch(options){
if(options && options.data){
options = _.extend({url : '/someendpoint/'}, options || {});
}
return Backbone.Collection.prototype.fetch.call(this, options);
}
当我在 View 中调用 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 进行字符串化的各种尝试中发生的情况
如果我像这样对整个选项对象进行字符串化
if(选项&&选项.数据){ 选项 = _.extend({url: '/someendpoint'}, 选项 || {}); options.data = JSON.stringify(options); console.log(options, "集合中的选项"); }
没有数据发送到服务器(并且没有调用正确的 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这会转换为 HTTP GET
。和we know根据规范,GET
请求应忽略所有数据负载。
所以...,我们要么必须将 range
数据附加到 URL,要么使用 POST
请求。
设置用于获取的网址参数
动态设置集合 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
属性来覆盖 fetch 时的 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()
使用 options
中的 type
属性覆盖该 prop,并提供 data
属性Backbone.ajax()
(顺便说一句,它只不过是 $.ajax
的一个薄包装器)。
注意:
This code is untested, please let me know if you run into any issues
关于javascript - 针对服务器请求对对象的一部分进行字符串化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29810190/