model.toJSON()返回空对象

时间:2012-03-07 17:05:20

标签: javascript backbone.js

我一直在玩Backbone.js并遇到了一些意想不到的事情。似乎toJSON()(以及作为属性的结果)只有在我明确设置属性时才会返回JSON对象。这是问题所在:

  1. 使用某些数据扩展/继承示例对象
  2. 抓住结果构造函数
  3. 实例化/新建一个实例
  4. 调用toJSON()函数
  5. 我希望调用返回带有所有属性(继承和绑定)的对象,但我得到了一个空的{}对象。

    以下是示例代码:

    var TestModelConstructor = Backbone.Model.extend({ name: "test", num: 483 });
    var testinstance = new TestModelConstructor;
    
    console.log(testinstance.name); //prints: test
    console.log(testinstance.num);  //prints: 483
    console.log(JSON.stringify(testinstance.toJSON())); //prints: {}
    console.log(testinstance.attributes); //again empty object
    
    testinstance.newattr = "adding new attribute";
    console.log(testinstance.attributes); //{}  ????
    
    //either set explicitly by calling "set" or via constructor/initialize
    testinstance.set({ label: "i can setz attributez" });
    console.log(JSON.stringify(testinstance.toJSON())); 
                                          //{"label":"i can setz attributez"}
    console.log(testinstance.attributes); //{"label":"i can setz attributez"}
    

    这种行为很奇怪,或者我遗漏了文档中的内容。

2 个答案:

答案 0 :(得分:3)

我认为您应该使用defaults参数extend来设置默认值。传递给extend函数的参数将是类的成员而不是属性,这是toJSON使用的。

var TestModelConstructor = Backbone.Model.extend({
    defaults : { name: "test", num: 483 }
});
var testinstance = new TestModelConstructor;
....

有关详细信息,请参阅defaults documentation

要清楚,Backbone.Model使用的属性存储在类的attributes成员中,而不是存储在实际的类本身中。这样可以避免将实际模型数据与您在模型上调用的函数和用于配置模型的设置混淆。将参数传递给Model.extend函数时,您正在创建/设置这些函数和设置。

因此,当您尝试设置testinstance.newattr时,您应该实际使用testinstance.attributes.newattr。这就是.set方法在幕后实际执行的操作,因此我建议您只使用.set

同样,attributes documentation有更多详情

答案 1 :(得分:1)

事实上你把它搞混了

你在哪里:

var TestModelConstructor = Backbone.Model.extend({ name: "test", num: 483 });

你应该做的:

var TestModelConstructor = Backbone.Model.extend({});

评论请记住,has不需要为空,但仅仅是为了测试在没有任何自定义方法的情况下扩展新模型就足够了。

然后,当你这样做时:

var testinstance = new TestModelConstructor;

你应该做的:

var testinstance = new TestModelConstructor({ name: "test", num: 483 });

备注在这里,您创建了一个已定义Model的新对象,并为modelObject提供了一些值,一个名称和一个数字。

这些属性仅在实例中可用,它们是实例的属性。 如果您希望这些属性作为每个实例的默认值,则应从Backbone.Model扩展时在模型定义中设置它们。像这样:

var TestModelConstructor = Backbone.Model.extend({
    defaults: {
        name: 'defaultname',
        num: 0
    }
});

备注您现在创建的每个实例都会将'defaultname'作为名称属性(除非您使用name属性的给定值创建实例。

总结一下:

var TestModelConstructor = Backbone.Model.extend({
    defaults: {
        name: 'defaultname',
        num: 0
    }
});

// create a test instance
var testinstance = new TestModelConstructor();

console.log(testinstance.get('name'));  // output:   defaultname

// create a testinstance and override the defaults (you can override them partially)
var testinstance2 = new TestModelConstructor({ name: "test", num: 483 });

console.log(testinstance.get('name'));  // output:   test