これは素晴らしい質問です。バックボーンは想定が不足しているため素晴らしいですが、このようなことを自分で実装する(方法を決定する)必要があることを意味します。自分のものを調べたところ、シナリオ1とシナリオ2が混在していることがわかりました。4番目の魔法のシナリオは、シナリオ1と2で行うことはすべて、完了しました。
例を挙げて、自分の扱い方を説明するのが最も簡単だと思います。この単純なページを指定されたビューに分割するとします。

HTMLは、レンダリングされた後、次のようになります。
<div id="parent">
<div id="name">Person: Kevin Peel</div>
<div id="info">
First name: <span class="first_name">Kevin</span><br />
Last name: <span class="last_name">Peel</span><br />
</div>
<div>Phone Numbers:</div>
<div id="phone_numbers">
<div>#1: 123-456-7890</div>
<div>#2: 456-789-0123</div>
</div>
</div>
うまくいけば、HTMLが図とどのように一致するかはかなり明白です。
ParentView2つのビューを保持している、InfoViewとPhoneListViewだけでなく、いくつかの余分なdiv要素の一つ、#nameいくつかの点に設定する必要があります。 エントリのPhoneListView配列である独自の子ビューを保持しPhoneViewます。
では、実際の質問に移ります。ビューのタイプに基づいて、初期化とレンダリングを異なる方法で処理します。私は自分の見解を2つのタイプ、ParentビューとChildビューに分けます。
それらの違いは単純です。Parentビューは子ビューを保持しますが、ビューは保持Childしません。したがって、私の例ではParentView、PhoneListViewはParentビューですが、InfoViewおよびPhoneViewエントリはChildビューです。
前に述べたように、これら2つのカテゴリの最大の違いは、レンダリングが許可されるタイミングです。完璧な世界では、Parentビューを一度だけレンダリングしたいです。モデルが変更されたときに再レンダリングを処理するのは、子ビュー次第です。Child一方、ビューには、他のビューに依存するビューがないため、必要なときにいつでも再レンダリングできます。
もう少し詳しく説明すると、Parentビューでは、initialize関数がいくつかのことをするのが好きです。
- 自分のビューを初期化する
- 自分のビューをレンダリングする
- 子ビューを作成して初期化します。
- 各子ビューにビュー内の要素を割り当てます(たとえば、
InfoViewが割り当てられます#info)。
ステップ1は自明です。
ステップ2、レンダリングは、子ビューが依存する要素が割り当てられる前にすでに存在するように行われます。これを行うことで、すべての子eventsが正しく設定されることがわかっているので、何も再委譲する必要を心配することなく、必要なだけ何度でもそれらのブロックを再レンダリングできます。renderここでは実際には子のビューはありませんinitialization。自分の中でそれを行うことを許可します。
手順3と4はel、子ビューの作成中に渡すと同時に実際に処理されます。親が自分のビューで子がコンテンツを配置できる場所を決定する必要があると思うので、ここに要素を渡したいと思います。
レンダリングについては、Parentビューではかなりシンプルに保つようにしています。render親ビューをレンダリングする以外に何もしないようにしたいのですが。イベントの委任、子ビューのレンダリング、何もありません。単純なレンダリング。
ただし、これが常に機能するとは限りません。たとえば、上記の例#nameでは、モデル内の名前が変更されるたびに要素を更新する必要があります。ただし、このブロックはParentViewテンプレートの一部であり、専用のChildビューでは処理されないため、回避します。要素のコンテンツを置き換えるだけで、要素全体を破棄する必要のない、ある種のsubRender関数を作成します。これはハックのように思えるかもしれませんが、DOM全体の再レンダリングや要素の再接続などを心配する必要があるよりも、うまく機能することがわかりました。本当にクリーンにしたい場合は、ブロックを処理する(と同様の)新しいビューを作成します。#name#parentChildInfoView#name
Childビューの場合、これはビューinitializationとかなり似ていParentますが、それ以上Childビューを作成する必要はありません。そう:
- ビューを初期化する
- セットアップは、気になるモデルへの変更のリスニングをバインドします
- ビューをレンダリングする
Childビューのレンダリングも非常に単純で、レンダリングしてmyのコンテンツを設定するだけelです。繰り返しになりますが、委任などをいじる必要はありません。
ここに私ParentViewがどのように見えるかのいくつかのサンプルコードがあります:
var ParentView = Backbone.View.extend({
el: "#parent",
initialize: function() {
// Step 1, (init) I want to know anytime the name changes
this.model.bind("change:first_name", this.subRender, this);
this.model.bind("change:last_name", this.subRender, this);
// Step 2, render my own view
this.render();
// Step 3/4, create the children and assign elements
this.infoView = new InfoView({el: "#info", model: this.model});
this.phoneListView = new PhoneListView({el: "#phone_numbers", model: this.model});
},
render: function() {
// Render my template
this.$el.html(this.template());
// Render the name
this.subRender();
},
subRender: function() {
// Set our name block and only our name block
$("#name").html("Person: " + this.model.first_name + " " + this.model.last_name);
}
});
subRenderここで私の実装を見ることができます。のsubRender代わりにバインドされた変更を使用することでrender、ブロック全体を爆破して再構築することを心配する必要はありません。
InfoViewブロックのサンプルコードは次のとおりです。
var InfoView = Backbone.View.extend({
initialize: function() {
// I want to re-render on changes
this.model.bind("change", this.render, this);
// Render
this.render();
},
render: function() {
// Just render my template
this.$el.html(this.template());
}
});
バインドはここで重要な部分です。モデルにバインドすることで、手動でrender自分を呼び出すことを心配する必要がなくなります。モデルが変更されると、このブロックは他のビューに影響を与えることなく、自身を再レンダリングします。
これPhoneListViewはに似ていParentViewます。コレクションを処理するにはinitialization、render関数と関数の両方にもう少しロジックが必要です。コレクションの処理方法は実際にはあなた次第ですが、少なくともコレクションイベントをリッスンし、どのようにレンダリングするか(追加/削除、またはブロック全体を再レンダリングする)を決定する必要があります。私は個人的には、新しいビューを追加して古いビューを削除するのが好きです。ビュー全体を再レンダリングするのではありません。
PhoneViewほぼ同じになるInfoViewだけで、それが気にモデルチェンジを聞いて、。
これで少しは助かったと思いますが、混乱していたり詳細が十分でない場合はお知らせください。