サーバーから受信したモデルのデータの一部を更新する必要がありました。 現在、2つのオプションがあります。 Model.set
呼び出すか、 Model.attributes
直接設定します。 変更を記録したくありませんsilent
たが、それぞれのビューを更新する必要があったため、
Backbone.Model.prototype.reset = (attributes, options) ->
attrs = attributes || {};
if options.parse
attrs = this.parse(attrs, options) || {}
@set(attrs, options);
<strong i="9">@changed</strong> = {};
Backbone.Model
Backbone.Collection
ようなリセットメソッドがないのはなぜだろうか?
リセットはエスケープハッチであり、必要であることがわかっているときに、効率的なレンダリングを一括で簡単に実行できます。
あなたの場合は、 set
使用してください。
属性を汚さずに設定できますか?
2014年8月1日には、7:28で、ジェレミー・アッシュケナスの[email protected]は書きました:
リセットはエスケープハッチであり、必要であることがわかっているときに、効率的なレンダリングを一括で簡単に実行できます。
あなたの場合は、setを使用してください。
—
このメールに直接返信するか、GitHubで表示してください。
呼び出しModel.clear()
の前にModel.set({})
あなたのケースで動作しますか? この方法では、現在の属性を拡張せず、代わりに置き換えられます。 Model.clear()
は、モデルで2つの「変更」イベントをトリガーしたくない場合のサイレントオプションもサポートします。
私はこの方法が欠けていることに同意します。 model.clear()
とmodel.set()
を組み合わせて使用することも考えました。 次に、 change
イベントを2回トリガーするという問題に遭遇しました。
model.clear()
呼び出すときにsilent
オプションを使用することはオプションではありません。これは、プロパティが設定解除されたときにchange
イベントを発生させたいためです。
model.reset()
メソッドは、新しい属性ハッシュを取得し、このハッシュに、新しい属性ハッシュに存在しない古い属性キーのundefined
値を入力します。
Model.prototype.reset = function(attrs, options) {
for (var key in this.attributes) {
if (key in attrs) continue;
attrs[key] = void 0;
}
return this.set(attrs, options);
};
@lennerd
どうですか:
Model.prototype.reset = function(attrs, options) {
for (var key in this.attributes) {
this.unset(key, {silent:true});
}
return this.set(attrs, options);
};
いいえ、これは役に立ちません。 モデルの現在の属性ハッシュにキーfoo
があるとします。これは、 model.reset()
渡す新しいattrs
ハッシュには存在しません。 change:foo
イベントをリッスンすると、サイレントモードでmodel.unset()
を使用したため、新しい値undefined
でトリガーされません。
Backbone.Model.prototype.reset = function(attrs, options) {
for (var key in this.attributes) {
this.unset(key, {silent:true});
}
return this.set(attrs, options);
};
var bar = new Backbone.Model();
bar.on('change', function(model) {
console.log('The model bar has been changed.');
});
bar.on('change:foo', function(model, foo) {
console.log('Foo has been changed to: ' + foo);
});
bar.set(foo, 'test');
// => The model bar has been changed.
// => Foo has been changed to: test
bar.reset({ foo2: 'test2' });
// => The model bar has been changed.
// Foo was resetted but no change event has been triggered.
かっこいい、私はあなたが意味することを理解します。 this.attributesを明示的にオーバーライドするよりもthis.unset(key, options)
を使用することを選択するでしょうが、それはattrs[key] = void 0;
を交換するだけの問題です:panda_face:
私はまだbackbone.jsに比較的慣れていないので、私が示す無知を許してください。しかし、議論されている振る舞いはModel.fetch
ように聞こえます。 説明は言う:
サーバーからモデルの状態をリセットします
change
イベントは引き続きトリガーされているように見えますが、モデルを「ダーティ」にしないでください。 サーバーの応答に基づいて属性をリセットしようとしているときに、このアプローチを採用できない理由はありますか? このような状況が発生する可能性があるのは、別の操作の副作用としてモデルが変更された場合だけだと思いますが、一般に、このような副作用はプログラミングが不十分であると見なされ、可能であれば回避する必要があります。 副作用を回避できない場合は、新しいモデル属性の代わりに「モデルXYZの更新」応答フラグを送信し、そのような応答が表示されるたびにfetch
をトリガーする方が理にかなっています。
繰り返しますが、私がこのコメントで示している無知を許してください。
@kolorahl 、
OPが達成したいのは、現在のモデル属性をクリアし、モデルの新しい属性となる新しいJSONを渡すことです。 このように、すでにJSONがある場合は、バックエンドにアクセスする必要はありません。
私はどういうわけか彼のclear + setメソッドで@ lupugabriel1に同意します。 しかし、これは考慮する必要がある機能の1つだと思います。 Backbone.Collection#resetのようなもの
私がこれを必要とした理由は、世界が変化しているからです。 バックボーンは、Model#fetch()XHRがサーバーからデータをロードするための主要なメソッドであると想定していますが、WebSocketを使用してさらに多くのことを行っています。 データがクライアントにプッシュされると、.fetchを呼び出すのは冗長であり、データをサイドロードし、トリガーするイベントフックを取得するための適切な方法が必要です。
#set
を使用しないのはなぜですか?
@jridgewellは、#setによって属性がダーティになるためです。 setを使ってみて、何が起こるか見てみましょう。
function callback(data_from_server) {
console.info(data_from_server);
m = new Backbone.Model(data_from_server);
m.set('foo', 'what?', {silent: true});
console.info(m.changedAttributes())
}
実際の結果:
{foo: 'bar'}
{foo: "what?"}
望ましい結果:
{foo: 'bar'}
false
状態がサーバーと同期していない状態に変更された場合はSetで問題ありませんが、サーバーとの同期として状態をマークする方法がないため、Model#resetが必要です。
私はこの機能のために別のモンキーパッチを書くことになりました:
/**
* Allow for side-loading data from the server, calling the sync event afterwards.
* <strong i="6">@param</strong> attributes
* <strong i="7">@param</strong> options
*/
Backbone.Model.prototype.sync_set = function(attributes, options) {
var attrs = attributes || {};
if (options.parse) {
attrs = this.parse(attrs, options) || {}
}
this.set(attrs, options);
this.changed = {};
this.trigger('sync', this, attributes, options);
return this;
}
function callback(data_from_server) {
console.info(data_from_server);
m = new Backbone.Model(data_from_server);
m.set('foo', 'what?', {silent: true});
console.info(m.changedAttributes())
}
{foo: 'bar'}
false
これはおそらく不足しているアイテムも設定解除する必要があります。 Model#set(attributes)がそれを行うかどうかはわかりません。
@lennerdが指摘したように、 clear()
続いてset()
呼び出すことは、適切なオプションではありません。
1)2つのchange
イベントを発生させ、
2) clear
呼び出しでsilent:true
を使用する場合、設定されていない属性の変更イベントは取得されません。
collection.reset()
は非常に直感的で、 Model
は同等の方法から本当に恩恵を受けることができると思います。 私はいつもmodel.reset(attrs)
を使おうとしていますが、そこにないときはいつもがっかりしています。 :(
私は先に進んで、Backbone.Modelに機能するreset
メソッドを追加するための小さな拡張機能を作成しました: Backbone-Model-Reset
同意する-ネイティブに持つと便利です。 clear()が行っていたように、「id」属性を操作せずに属性をリセットする必要がありました。 これがその
@ thesmart 、Model#setは欠落している属性の設定を解除しないため、Model#resetが必要だと思います。
問題をクローズするときに理由を説明する必要があります。 @ akre54がこれを閉じた理由を知りたいのですが。 バックボーンモデルは意図的に原始的であり、非ピニオン化されていますが、Model#resetがないことは、モデルの使用方法についての意見を表しています。 http://backbonejs.org/#Getting-startedから
哲学的には、Backboneは、JavaScriptを使用してWebアプリケーションを構築するときに一般的に役立つデータ構造化(モデルとコレクション)およびユーザーインターフェイス(ビューとURL)プリミティブの最小限のセットを発見する試みです。
私の知る限り、BackboneのデータモデルはRESTと互換性がありません
後にクライアントのサーバー状態を安全にモデル化する方法がないため
モデルが構築されました。 新しいモデルを構築することが、取得する唯一の方法です。
リセットなしの新しい状態。
2016年7月5日(火曜日)に、pgifford [email protected]は書きました:
@thesmart https://github.com/thesmart、Model#setは欠落を解除しません
Model#resetが必要だと思うのはそのためです。問題をクローズするときに理由を説明する必要があります。 私は
@ akre54https ://github.com/akre54がこれを閉じた理由を知りたい。
バックボーンモデルは意図的に原始的で非ピニオン化されていますが、
Model#resetの欠如は、モデルの使用方法についての意見を表しています。 から
http://backbonejs.org/#Getting -started哲学的には、バックボーンは最小限のセットを発見する試みです
データ構造化(モデルとコレクション)とユーザーインターフェイス(ビューと
URL)Webアプリケーションを構築するときに一般的に役立つプリミティブ
JavaScriptを使用します。—
あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/jashkenas/backbone/issues/3253#issuecomment -230586424、
またはスレッドをミュートします
https://github.com/notifications/unsubscribe/AARJLQ8-BGeV0X_owHVpyPQAdeiMweNMks5qSriDgaJpZM4CTBHH
。
モデルreset
必要だったので、先に進んでBackboneの_spirit_で作成しました。 私はこれをBackboneの個人的な拡張で使用します。
単純な.clear
後に.set
.clear
続くよりも優れています。これは、デフォルトをモデルにマージし、渡された属性が初期化のようにそれらをオーバーライドできるようにするためです。
/**
* Clears the model's attributes and sets the default attributes.
* <strong i="10">@param</strong> {Object} attributes to overwrite defaults
* <strong i="11">@param</strong> {Object} options to pass with the "set" call.
* <strong i="12">@return</strong> {Backbone.Model} this object, to chain function calls.
*/
reset: function(attributes, options) {
options = _.extend({ reset: true }, options);
// ensure default params
var defaults = _.result(this, 'defaults'),
attrs = _.defaults(_.extend({}, defaults, attributes || {}), defaults);
// apply
this._reset(attrs, options);
// triggers a custom event, namespaced to model in order
// to avoid collision with collection's native reset event
// when listening to a collection.
if (!options.silent) this.trigger('model:reset', this, options);
return this;
},
/**
* Private method to help wrap reset with a custom behavior in child
* classes.
* <strong i="13">@param</strong> {Object} attributes to overwrite defaults
* <strong i="14">@param</strong> {Object} options to pass with the "set" call.
*/
_reset: function(attrs, options) {
this.clear({ silent: true }).set(attrs, options);
},
silent: true
ない場合は、カスタムmodel:reset
イベントに加えて、変更イベント( change
およびchange:attribute
)をトリガーします。 model:reset
イベントのみをトリガーするように簡単にカスタマイズできますが、モデルをリセットするときは常に変更イベントをトリガーする必要があると思います。
lennerd https://github.com/jashkenas/backbone/issues/3253#issuecomment-58789524のソリューションを少し調整しました。
Backbone.Model.prototype.reset = function(attrs, options) {
var missing = {};
for (var key in this.attributes) {
if (key in attrs) continue;
attrs[key] = undefined;
missing[key] = true;
}
// trigger all change events at the same time
this.set(attrs, options);
// remove missing attributes completely
for (var key in missing) {
// no silent option here in case attributes changed again meanwhile (edge case)
this.unset(key)
}
return this;
};
最も参考になるコメント
@ thesmart 、Model#setは欠落している属性の設定を解除しないため、Model#resetが必要だと思います。
問題をクローズするときに理由を説明する必要があります。 @ akre54がこれを閉じた理由を知りたいのですが。 バックボーンモデルは意図的に原始的であり、非ピニオン化されていますが、Model#resetがないことは、モデルの使用方法についての意見を表しています。 http://backbonejs.org/#Getting-startedから