web-dev-qa-db-ja.com

Backbone.jsで、サイレント変更が最終的に変更イベントをトリガーするのはなぜですか?

バックボーンモデルで属性を設定しているときに{"silent":true}を渡すと、change:attributeイベントが抑制されないのはなぜですか?次に属性が変更されたときにそのイベントを発生させる利点は何ですか?

更新

バックボーン0.9.10は、{ "silent": true }を渡す動作を変更しました。変更ログから:

変更時に{silent:true}を渡すと、個々の「change:attr」イベントが遅延することはなくなり、代わりに完全に無音になります。

変更ログを参照する ここ

26
stinkycheeseman

これもしばらくの間私を混乱させました。

その理由は、{silent:true}はnotは「すべてを通常どおりに実行しますが、イベントをトリガーしない」という意味ではないためです。

@jashkenasによるさまざまなコメントと回答から、「属性値を変更するだけで(そして、それを「changedAttributes」ハッシュに追加する)、他のすべての「変更関連」アクティビティを後で実行する」という意味のようです。

'silent'はpreventその/それらのプロパティのchangeイベントではなく、次のchangeイベントがトリガーされるまで 'announcement'をキューに入れます。

したがって、おそらくdeferのような名前の方が適切です。

関連情報:

https://github.com/documentcloud/backbone/pull/85

「サイレント」変更のポイントは、モデルの観点からは変更とは見なされないということです。後で実際に変更が発生すると、一度に完全な違いが得られます。

https://github.com/documentcloud/backbone/issues/87

サイレント変更のポイントは、実際に変更を加えることなく、一時的にモデルの内部状態をいじることができるということです。その後、属性が実際に変更されると、検証が実行され、イベントが発行されます。サイレント変更を行うときにエラーイベントを発行することは意味がありません。

2013年4月7日更新

注:動作を確認するためにこれをテストしていません。これはリリースノートを読んだことに基づいています...

Backbone 0.9.10以降、上記の動作が変更されました。そのバージョン(およびそれ以降)では、silent:truechange:attrイベントを完全に抑制します-単に遅延させるだけではありません。

http://backbonejs.org/#changelog

30
Edward M Smith

バックボーン0.9.2では、set関数は、変更が更新される前に検証を実行します。

_  // Run validation.
  if (!this._validate(attrs, options)) return false;
_

_{silent: true}_オプションが渡された場合、検証コードは実行されません。

_  if (options.silent || !this.validate) return true;
_

つまり、model.set({value: 100}, {silent: true});は「無効な」値をモデルに設定できるため、属性は更新されますが、変更イベントは発生しません。

一部のフィールドを更新してモード全体の検証を防止したい場合は便利です。そのため、モデルがまだ完了していない場合でも、変更は属性に伝播されます。ただし、通常はビューにも変更を表示する必要があるため、手動でmodel.change()またはmodel.trigger('change:value', model, value)を呼び出す必要があります。

2