あなたが自分で言ったように、あなたのオプションは両方とも非常に複雑に見えます。しかし、場合によっては、さらに複雑になることが必要悪になることもあります。ただし、更新されたフィールドが比較的単純なもの (値を要素または入力フィールドにバインドするなど) である場合は、追加のビュー/テンプレートの抽象化を作成せずに DOM 要素を更新するだけです。
モデルがあるとします:
var person = new Person({ firstName: 'John', lastName: 'Lennon', instrument:'Guitar' });
そして、次のテンプレートをレンダリングするビュー:
<div>First Name: <span class="firstName">{{firstName}}</span></div>
<div>Last Name: <span class="lastName">{{lastName}}</span></div>
<div>Instrument: <input class="instrument" value="{{instrument}}"></input></div>
どのプロパティ変更がどの要素を更新するかをビューで宣言し、モデルchange
イベントをそれらを更新する関数にバインドできます。
var PersonView = Backbone.View.extend({
//convention: propertyName+"Changed"
//specify handler as map of selector->method or a function.
firstNameChanged: { '.firstName': 'text' },
lastNameChanged: { '.lastName': 'text' },
instrumentChanged: { '.instrument': 'val' },
otherFieldChanged: function(val) { //do something else },
initialize: function (opts) {
this.model.on('change', this.update, this);
},
//called when change event is fired
update: function(state) {
_.each(state.changed, function(val, key) {
var handler = this[key + "Changed"];
//handler specified for property?
if(handler) {
//if its a function execute it
if(_.isFunction(handler)) {
handler(val);
//if its an object assume it's a selector->method map
} else if(_.isObject(handler)) {
_.each(handler, function(prop, selector) {
this.$(selector)[prop](val);
}, this);
}
}
}, this);
}
クラス化された要素を DOM に追加し、それらをビュー コードで維持する必要があるため、このようなソリューションは非常に複雑なビューには対応できません。しかし、より単純なケースでは、これは非常にうまくいくかもしれません。
さらに、ビューが自然にセクションに分割される場合は、複数の小さなビューのビューを構成することを試みることは常に良いことです。そうすれば、単一のフィールドを個別に更新する必要がなくなります。