同期時にモデルから特定のプロパティを除外する方法はありますか?
たとえば、あるビューステートに関するモデル情報を保持しています。ピッカーモジュールがあり、このモジュールがselected
モデルの属性を切り替えるだけだとします。後でコレクションを呼び出すときに、の値を無視して、サーバーへの同期から除外し.save()
たいと思います。selected
そうするためのクリーンな方法はありますか?
(詳細が必要な場合はお知らせください)
同期時にモデルから特定のプロパティを除外する方法はありますか?
たとえば、あるビューステートに関するモデル情報を保持しています。ピッカーモジュールがあり、このモジュールがselected
モデルの属性を切り替えるだけだとします。後でコレクションを呼び出すときに、の値を無視して、サーバーへの同期から除外し.save()
たいと思います。selected
そうするためのクリーンな方法はありますか?
(詳細が必要な場合はお知らせください)
これは最良の解決策のようです(@nikoshr参照質問に基づく)
Backbone.Model.extend({
// Overwrite save function
save: function(attrs, options) {
options || (options = {});
attrs || (attrs = _.clone(this.attributes));
// Filter the data to send to the server
delete attrs.selected;
delete attrs.dontSync;
options.data = JSON.stringify(attrs);
// Proxy the call to the original save function
return Backbone.Model.prototype.save.call(this, attrs, options);
}
});
そのため、モデル インスタンスの保存関数を上書きしますが、必要のないデータを除外し、それを親のプロトタイプ関数にプロキシします。
Underscore 1.3.3 ではpickが追加され、1.4.0 では omit が追加されましたtoJSON
。これは、モデルの関数をオーバーライドして属性をホワイトリストに登録する_.pick
か、属性をブラックリストに登録するために非常に簡単に使用できます_.omit
。
またtoJSON
、データをサーバーに渡すために sync コマンドで使用されるため、他の場所でこれらのフィールドを使用したくない場合、これは良い解決策だと思いますtoJSON
。
Backbone.Model.extend({
blacklist: ['selected',],
toJSON: function(options) {
return _.omit(this.attributes, this.blacklist);
},
});
私の解決策は上記のすべてを組み合わせたものです。ブラックリストの代わりにホワイトリストを使用してください..これは一般的に良いルールです
定義
attrWhiteList:['id','biography','status'],
そして保存を上書きします
save: function(attrs, options) {
options || (options = {});
//here is whitelist or all
if (this.attrWhiteList != null )
// Filter the data to send to the server
whitelisted = _.pick(this.attributes, this.attrWhiteList);
else
whitelisted =this.attributes;
/* it seems that if you override save you lose some headers and the ajax call changes*/
// get data
options.data = JSON.stringify(whitelisted);
if ((this.get('id') == 0) || (this.get('id') == null))
options.type = "POST"
else
options.type = "PUT";
options.contentType = "application/json";
// options.headers = {
// 'Accept': 'application/json',
// 'Content-Type': 'application/json'
// },
// Proxy the call to the original save function
return Backbone.Model.prototype.save.call(this, attrs, options);
},
実際、バックボーンの保存または同期機能をいじることなくこれを達成するためのはるかに簡単な方法があります。
backbone.js の 1145 行目を見ると、
// Ensure that we have the appropriate request data.
if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
params.contentType = 'application/json';
params.data = JSON.stringify(options.attrs || model.toJSON(options));
}
これは、オプションにデータを入れることで、xhr のデータ部分をオーバーライドできることを意味します。
バックボーンの保存には model.save([attributes], [options]) が必要なので
ただし、適切な保存には id などの属性が不可欠である可能性があることを覚えておいてください
例
model.save( {}, { data: JSON.stringify(data) } ) ;
だからあなたはこのようなことをしているはずです
var data = { id : model.id , otherAttributes : 'value' } ;
model.save( {}, { data : JSON.stringify(data) } );
これは私にとって非常にうまく機能し、フェッチ、保存、削除などのxhrを使用するバックボーンで使用できます...
いくつかの回答に基づいて、これは null オブジェクトのケースと、既に設定されているcontentType
場合を送信しないバックボーンの条件を説明します。options.data
EDITABLE_ATTRIBUTES = ["name", "birthdate", "favoriteFood"];
...
save: function(attrs, options) {
// `options` is an optional argument but is always needed here
options || (options = {});
var allAttrs = _.extend({}, this.attributes, attrs);
var allowedAttrs = _.pick(allAttrs, EDITABLE_ATTRIBUTES);
// If `options.data` is set, Backbone does not attempt to infer the content
// type and leaves it null. Set it explicitly as `application/json`.
options.contentType = "application/json";
options.data = JSON.stringify(allowedAttrs);
return Backbone.Model.prototype.save.call(
this, allowedAttrs, options);
},
save
使用するので、toJSON
それをオーバーライドします:
toJSON: function(options) {
var attr = _.clone(this.attributes);
delete attr.selected;
return attr;
},
selected
ただし、たとえば toJSON を使用していて、ビューが必要な場合は機能しない可能性があります。それ以外の場合は、おそらくメソッドをオーバーライドする必要がありますsave
。
options.attrs を設定すると、API パラメータをカスタマイズできます。
var model = new Backbone.Model();
model.save(null, {
wait: true,
success: function() {
},
attrs: _.omit(model.attributes, 'selected')
});
必要な値のみを設定するには、HTTP POST の代わりに HTTP PATCH を使用します。バックボーン側では、save メソッドに patch 属性を追加するだけです。
entity.save(data,{patch:true})
この属性で保存を使用すると、渡されたフィールドのみがdata
サーバーに送信されます。
1 回限りの場合はmode.unset('selected', { silent:true })
、属性を削除するために使用できます (silent は、変更イベントの発生を回避するためだけに設定されます)。けれど。
とはいえ、上記のソリューションの1つを完全に支持します。さらに、これがより定期的に必要なものである場合。
これと同じ問題があるため、役立つ小さなモジュールを作成することにしました: https://github.com/lupugabriel1/backbone-model-save
これをモデルで使用する方法は次のとおりです。
var myModel = new Backbone.ModelSave.extend({
notSync: ['name', 'age']
});