web-dev-qa-db-ja.com

モデル内のモデル属性にアクセスするbackbone.js-this.attributeVS this.get( 'attribute')?

私の理解では、Backbone.jsモデルの属性は、次のように言うことで、ややプライベートなメンバー変数として宣言されることになっています。

this.set({ attributeName: attributeValue })
// accessing the value
this.get('attributeName');

しかし、実際のモデルで関数を書いているときは、次のように言う方がはるかに簡単に思えます。

this.attributeName = attributeValue;
// accessing the value
this.attributeName;

また、後者のバージョンはbackbone.jsのイベント管理を経由しないため、処理が高速になると思います。

そのため、主にモデルの内部で使用される属性をプロがどのように使用するのか疑問に思いました。これらは、実際には外部から少しシールドしたい属性であるため、後者の例のように露出させることは、まだ正しくない可能性があります。 getメソッドとsetメソッドを持たないbackbone.jsビューの例を見てきたとき、2番目の例のように行うのは問題ないようです。では、モデル内でコーディングするときにget/set(attribute)またはthis.attributeを使用する場合の経験則はありますか?それとも、これをより明確にするモデルの例ですか?

16
torno

model.get(property)およびmodel.set(...)を使用する場合

モデルのデータにアクセスするには、getsetを使用する必要があります。これは、fetchを使用して取得され、saveを使用して永続化される、モデルのシリアル化された表現の一部である属性を意味します。

いつ_model.attributes.property_を使用するか

決して。

_model.attributes_オブジェクトに直接アクセスするのではなく、常にget、特にsetを使用する必要がありますが、これについては相反する意見があります。 modelとそのコンシューマーの間には契約があり、changeイベントを使用してモデルのデータへの変更をコンシューマーに通知できることが保証されていると思います。内部属性オブジェクトを直接変更すると、イベントは送信されず、このコントラクトは破られます。バックボーンイベントは非常に高速です。特に、リスナーがアタッチされていない場合は、過度に最適化してもメリットはありません。

getの代わりに属性に直接アクセスすること自体はまったく無害ですが、attributesオブジェクトを完全にプライベートと見なすことができるように、回避する必要があります。

一部の変更トリガーイベントを絶対に防ぐ必要がある場合は、_silent:true_オプションを使用できます:model.set({key:val}, {silent:true})。これは前述の契約を破り、Backbone自身のドキュメントでさえ次の警告を与えます。

これが良い考えになることはめったにない、おそらく決してないことに注意してください。イベントコールバックのオプションで特定のフラグを通過させて確認し、無視することを選択すると、通常はうまくいきます。

いつ_model.property_を使用するか

データではないプロパティ、つまり一時状態変数、計算されたプロパティなどは、モデルエンティティに直接アタッチできます。これらのプロパティは一時的で推移的であると見なす必要があります。モデルの初期化時またはその存続期間中に再作成できますが、パブリックかプライベートかに関係なく、永続化しないでください。一般的な命名規則は、次のようにプライベートプロパティの前に___文字を付けることです。

_this._privateProperty = 'foo';
this.publicProperty = 'bar';
_
55
jevakallio

決して不完全な答えではありません。

モデル属性のコレクションにアクセスしたい場合があります-それらの属性が何であれ。属性の計算を実行したり、出力用にフォーマットしたりするためのユーティリティメソッドを検討してください。

これを行う便利な方法は、model.attributesにアクセスすることです。

以下の1つの代替案を検討してください。

var attributesNames = ['foo', 'bar', 'baz'];
var attributes = _(attributesNames ).map(function(attr) { return model.get(attr); });

callSomeUtilityMethod(attributes);

2つの問題:

  • 「attributeNames」コレクションにカップリングを導入しました。そのリストが変更された場合はどうなりますか?
  • 名前と値の関連付けが失われました。上記の地図を書き直すこともできますが、手間がかかります。

このシナリオでは、次のようなことを行う方がはるかに便利です。

callSomeUtilityMethod(model.attributes);
2
Aaron Averill