特に、計算されたプロパティ、ember-data属性、またはコントローラーを介してさまざまな状況を処理するember / ember-dataを使い始めて以来、Backbone.jsで非永続属性を処理することに頭を悩ませてきました。
多くのソリューションは、メソッドをカスタマイズすることを提案していtoJSON
ます。ただし、一部の一般的なBackboneプラグイン(特にネストされたモデルを処理するプラグイン)は、独自のtoJSON
メソッドを実装し、を呼び出してBackbone.Model.prototype.toJSON
モデルの属性のオブジェクト表現を取得します。したがってtoJSON
、モデル定義のメソッドを上書きすると、これらのプラグインのいくつかの(潜在的に重要な)機能が失われます。
私が思いついた最善の方法は、モデル定義にキーの配列を含め、メソッド自体excludeFromJSON
を上書きすることです。toJSON
Backbone.Model.prototype
Backbone.Model.prototype.toJSON = function() {
var json = _.clone(this.attributes),
excludeFromJSON = this.excludeFromJSON;
if(excludeFromJSON) {
_.each(excludeFromJSON, function(key) {
delete json[key];
});
}
return json;
};
MyModel = Backbone.Model.extend({
excludeFromJSON: [
'inches'
]
});
このように、非永続キーを定義するだけで済みます(定義するのを忘れた場合、サーバーがエラーをスローしたときにすぐに通知されます!)。プロパティが存在toJSON
しない場合、通常どおりに動作します。excludeFromJSON
あなたの場合、inches
はから派生した計算されたプロパティであるmm
ため、これをモデルのメソッドとして実装することは理にかなっています(mmが変更されたときにインチの値が正しいことを確認します)。
MyModel = Backbone.Model.extend({
inches: function() {
return this.get('mm') / 25;
}
});
ただし、これには、他のすべての属性とは異なる方法でアクセスされるという欠点があります。理想的には、他の属性へのアクセスと一貫性を保つ必要があります。これは、デフォルトの方法を拡張するget
ことで実現できます。
var getMixin = {
get: function(attr) {
if(typeof this[attr] == 'function') {
return this[attr]();
}
return Backbone.Model.prototype.get.call(this, attr);
}
};
MyModel = Backbone.Model.extend({
inches: function() {
return this.get('mm') / 25;
}
});
_.extend(MyModel.prototype, getMixin);
これにより、次のことが可能になります。
new MyModel().get('inches');
このアプローチは、基になるattributes
ハッシュには影響しません。つまり、後で値を指定しない限り、表現にinches
は表示されません。この場合、配列のようなものが必要になります。toJSON
set
inches
excludeFromJSON
値が必要な場合は、変更をリッスンして次set
のinches
値を調整することもできますmm
。
MyModel = Backbone.Model.extend({
initialize: function() {
this.on('change:inches', this.changeInches, this);
},
inches: function() {
return this.get('mm') / 25;
},
changeInches: function() {
this.set('mm', this.attributes.inches * 25);
}
});
_.extend(MyModel.prototype, getMixin);
JSBinの完全な例を参照してください。
このメソッドの(公式?)目的がtoJSON
、サーバーと同期するためのモデルを準備することとして最近再定義されたことも注目に値します。このため、呼び出しtoJSON
は常に「永続的」(または「保存可能」)属性のみを返す必要があります。