ビューをレンダリングしているが、そのビューが依存するモデルがまだロードされていないという状況に陥ることがよくあります。ほとんどの場合、URL から取得したモデルの ID だけを持っています。たとえば、仮想市場アプリケーションの場合、ユーザーはその URL でアプリにアクセスします。
http://example.org/#/products/product0
myProductView
で、 を作成してProductModel
その ID を設定し、product0
次に I fetch()
. プレースホルダーを使用して 1 回レンダリングし、フェッチが完了したら再レンダリングします。しかし、もっと良い方法があることを願っています。
何かをレンダリングする前にモデルが読み込まれるのを待つと、反応が鈍くなります。再レンダリングするとちらつきが発生し、「読み込み中... お待ちください」またはスピナーをどこにでも追加すると、ビュー テンプレートが非常に複雑になります (特に、モデルが存在しないか、ユーザーが表示する権限がないためにモデルのフェッチが失敗した場合)ページ)。
では、モデルがまだない場合にビューをレンダリングする適切な方法は何でしょうか?
ハッシュタグ ビューから離れて を使用する必要がありますpushState
か? サーバーはプッシュできますか? ぜひ聞きたいです。
すでに読み込まれたページからの読み込み:
ページに直接着陸するのではなく、既にページが読み込まれているときにできることはもっとあると思いProduct
ます。
コレクションをレンダリングするなどして、アプリが製品ページへのリンクをレンダリングする場合、ProductOrder
他にできることはありますか?
<ul id="product-order-list">
<li>Ordered 5 days ago. Product 0 <a href="#/products/product0">(see details)</a></li>
<li>Ordered 1 month ago. Product 1 <a href="#/products/product1">(see details)</a></li>
</ul>
このリンクから詳細ページへのパターンを処理する私の自然な方法は、次の行に沿って何かを行うルートを定義することです。
routes: {
'products/:productid': 'showProduct'
...
}
showProduct: function (productid) {
var model = new Product({_id: productid});
var view = new ProductView({model: model});
//just jam it in there -- for brevity
$("#main").html(view.render().el);
}
fetch()
次に、ビューのinitialize
関数内で呼び出しthis.render()
、this.listenTo('change', ...)
イベント リスナーから呼び出す傾向があります。これにより、複雑なrender()
ケースが発生し、オブジェクトが表示されたり、ビューから消えたりします。たとえば、私のビュー テンプレートでは、Product
ユーザー コメント用に画面の一部を予約している可能性がありますが、製品にコメントが存在する/有効になっている場合に限られます。これは、モデルがサーバーから完全にフェッチされるまでは一般的にわかりません。
では、どこで/いつフェッチを行うのが最適でしょうか?
ページが遷移する前にモデルをロードすると、ビュー コードは単純になりますが、ユーザーが認識できるほどの遅延が発生します。ユーザーはリスト内のアイテムをクリックし、モデルが返されるまで (ページが変更されることなく) 待つ必要があります。応答時間は重要であり、これについてのユーザビリティ調査は行っていませんが、ユーザーはリンクをクリックするとすぐにページが変更されることに慣れていると思います。
ProductView
モデルをの内にロードし、モデル イベントをリッスンすると、2 回レンダリングする必要があります。1 回目は空のプレースホルダーを使用して (そうしないと、白いページを見つめる必要があるため)、1 回後ですinitialize
。this.model.fetch()
読み込み中にエラーが発生した場合は、ビューを消去して (ちらつき/グリッチに見える)、何らかのエラーを表示する必要があります。
おそらくビュー間で再利用できる遷移読み込みページを含む、私が見ていない別のオプションはありますか? render()
または、スピナー/読み込みインジケーターを表示するために常に最初の呼び出しを行うことをお勧めしますか?
編集:経由でロードcollection.fetch()
アイテムはすでにリストされているコレクション (リンクのリストをレンダリングするために使用されるコレクション) の一部であるため、リンクがクリックされる前に、collection.fetch()
. コレクションが実際に のコレクションである場合Product
、製品ビューをレンダリングするのは簡単です。
Collection
ただし、リストの生成に使用される は ではない場合がありますProductCollection
。ProductOrderCollection
製品 ID (または、製品 ID へのリンクを表示するのに十分な量の製品情報) への参照を単に持つ、または何か他のものである可能性があります。
モデルが大きい場合、 Product
a を介してすべてを取得するcollection.fetch()
ことも禁止される場合があります。Product
製品リンクの 1 つがクリックされる可能性は低いです。
鶏か卵か?このcollection.fetch()
アプローチは、製品ページに直接移動するユーザーの問題も実際には解決しません...この場合、ID (または製品ページにあるもの) だけからモデルを取得ProductView
する必要があるページをレンダリングする必要があります。 Product
URL)。