バックボーンボイラープレートを使用してテンプレートをレンダリングしています。そのfetchTemplateメソッドは、レンダリングされたテンプレートをキャッシュします。
アコーディオンの初期化など、レンダリングされたコンテンツに対して追加のコードを実行したいのですが、非同期でコンパイルされたテンプレートを使用してこれを実行するのは、思ったよりも難しいです。
次に例を示します。
Duel.Views.Home = Backbone.View.extend({
template: "/templates/duel_home.jade",
render: function() {
var view = this;
statusapp.fetchTemplate(this.template, function(tmpl) {
$(view.el).html( tmpl({duels: view.collection.toJSON()}) );
view.postrender();
});
return this;
},
postrender: function() {
$('#duel-new').each(function() {
console.log('Found something')
});
}
});
上記のほかに、 http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/で概説されているビューハンドラーを使用します
これは私が次のようなことをします
var view = Duel.Views.Home({model: mymodel})
viewHandler('#content').showView(view)
これは呼び出します
$('#content').html(view.render().el)
ただし、テンプレートがまだキャッシュされていない場合は、最初にレンダリングが呼び出され、時間どおりにポストレンダリングが呼び出されます。一方、テンプレートがすでにキャッシュされている場合、テンプレートはすぐにレンダリングされ、postrenderが呼び出されview.el
ますが、まだDOMに挿入されていないため、$(this.el)は空のリストであり、$('#duel -new')。each()は「void」です。
もちろん、viewHandlerのrender呼び出しの後にpostrenderメソッドを追加することもできますが、これは同じ問題を引き起こしますが、renderメソッドの最初の呼び出しで発生します。テンプレートはまだコンパイルされていないため、postrenderはその要素が存在する前に呼び出されます。したがって、これらの存在しない要素にハンドラーを定義することはできません。
この問題を適切に克服する方法についてのアイデアはありますか?たとえば、.onを使用した単純なクリックイベントの場合は比較的簡単ですが、たとえば、より一般的な構造については$('#tabs').tabs()
どうでしょうか。
私のfetchTemplate関数は次のとおりです。
fetchTemplate: function(path, done) {
window.JST = window.JST || {};
// Should be an instant synchronous way of getting the template, if it
// exists in the JST object.
if (JST[path]) {
return done(JST[path]);
}
// Fetch it asynchronously if not available from JST
return $.get(path, function(contents) {
var tmpl = jade.compile(contents,{other: "locals"});
JST[path] = tmpl;
return done(tmpl);
});
},