为什么Backbone.Model.fetch()在包装器中返回数据?

时间:2013-09-08 23:47:39

标签: javascript backbone.js

假设我有一个Backbone.js模型:

// I declare it...
var Foo = Backbone.Model.extend({
  url: '/resources/foo',
  defaults: {
    bar: true
  }
});

//  Construct it...
var foo = new Foo({});

// Locally set a value,
foo.set('floozy', true);

// And then fetch more data on it from the server.
foo.fetch();

现在说服务器返回一个对象:

{
  id: 1
  bar: false,
  floozy: false
}

如果我在获取成功时检查模型内容,

foo.fetch({ success: function(){
  console.log(this.toJSON());
}});

在firebug中检查模型,对象看起来像这样:

{
  0: {
    id: 1,
    foo: false,
    floozy: false,
  },
  foo: true,
  floozy: true
}

换句话说,它不是更新我现有的值,而是将整个响应包装在一个未命名的对象(0)中。我还没弄清楚为什么会这样,我很难过。为什么会这样?我做错了什么?

1 个答案:

答案 0 :(得分:4)

您的服务器没有返回您认为的内容,它返回的数组包含如下所示的单个元素:

[{"id":1,"bar":false,"floozy":false}]

你的结果的这一部分是死的:

0: { ... }

它看起来像一个单元素数组,已被解释为一个简单的键/值对象。我也知道这一点,因为我可以在jsfiddle.net上复制你的结果,如下所示:

var json = JSON.stringify([{id: 1, bar: false, floozy: false}]);
var M = Backbone.Model.extend({
    url: '/echo/js?js=' + encodeURIComponent(json),
    defaults: {
        bar: true
    }
});

var m = new M;
m.set('floozy', true);
m.fetch({
    success: function(m) {
        console.log(m.toJSON());
    }
});

导致奇怪的熟悉:

0: Object
    bar: false
    floozy: false
    id: 1
bar: true
floozy: true

在控制台中。

演示:http://jsfiddle.net/ambiguous/QF8ue/

您可以通过修复服务器代码或向模型添加parse来解决此问题:

parse: function(response) {
    return _(response).isArray()
         ? response[0]
         : response;
}

我进行了_.isArray调用,以便您的模型可以处理已包装和未包装的数据。

演示:http://jsfiddle.net/ambiguous/atSDp/