2012-03-07 7 views
2

私はBackbone.jsで遊んでいて、少し予期せぬものに遭遇しました。それは、明示的に属性を設定した場合、toJSON()(および属性の結果として)はJSONオブジェクトを返すように見えます。ここに問題があります:model.toJSON()は空のオブジェクトを返します

  1. は、いくつかのデータ
  2. とサンプルオブジェクトは、私が予想結果のコンストラクタ
  3. インスタンス化/新しいインスタンス
  4. コールtoJSON()機能

をつかむ継承/拡張しますすべての属性(継承されバインドされている)を持つオブジェクトを返すために呼び出す代わりに、空の{}オブジェクトを戻しました。

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"} 

いずれかのこの動作は奇妙であるか、私はドキュメントに何かを逃した:

は、ここでのサンプルコードです。

答えて

3

extendのデフォルトの値を設定するには、defaultsパラメータを使用する必要があります。 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は、より詳細に

+0

ありがとうございます。属性セクションをもう一度参照すると、質問が明確になります。このMVCフレームワークで使用されている規約の概要については、ドキュメントがより明確であることを願っています。イオンである。 –

+0

問題ありません。私は実際には、あなたが必要とする情報の大半がドキュメントにあることがわかったので、それを得るためにはちょっとした読みが必要です。とにかく、これが正しい答えだと思うなら、それを正しいものとしてマークしてください。 – obmarg

1

を持って実際には、あなたがやった

それを混同:

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

あなたが行っている必要があります。

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

発言を eは空である必要はありませんが、カスタムメソッドなしで新しいモデルをテストするだけで十分です。あなたがやったとき

そして、:

var testinstance = new TestModelConstructor; 

はあなたが行っている必要があります。ここに

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

発言、あなたはその定義されたモデルの新しいオブジェクトを作成し、あなたのmodelObjectいくつかを与えます値、名前、および数値。

これらの属性はインスタンスでのみ使用できますが、インスタンスのプロパティです。 から拡張するときにモデル定義で設定する必要があるすべてのインスタンスでこれらのプロパティをデフォルトとして使用する場合は、 を使用します。 。このように:あなたはnameプロパティに指定した値を使用してインスタンスを作成しない限り

それを合計する

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

あなたが今作成発言すべてのインスタンスは、(nameプロパティとして'defaultname'を取得します。

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 
+0

この優れた発言をお寄せいただきありがとうございます。私は、インスタンスの値のコンストラクタを明示的に設定することと、デフォルトを使用するというプロトタイプ継承の側面を完全に欠いていました。最初のバージョン(質問)を試してみると、モデル自体のものではなく、モデルのプロトタイプの属性が見えましたが、当時はあまり注意を払っていませんでした。しかし、これは確かにものを視点に置くのに役立ちます。 –

関連する問題