我正在使用Backbone.js v0.5.5處理單頁應用程序,並且在應用程序的一個「頁面」上有一個Master View(audioOnDemand)和兩個輔助視圖(audioPlay和audioNav)。我希望輔助視圖是可路由的,以便用戶可以作爲示例轉到'#audio_ondemand','#audio_ondemand/id /:id'或'#audio_ondemand/page /:page',並且所有內容都會加載。爲了做到這一點,我最終不得不在我的控制器/路由器中放置一些jQuery代碼,這感覺很不方便。這就是爲什麼我在這裏,看看有沒有更好的方法。Refactor Me:Backbone.js子視圖渲染優化
這是我的控制器/路由器。
audio_ondemand: function(splat) {
this._audioondemandview = new AudioOnDemandView();
this._audioondemandview.render();
if (splat) {
var id_patt = /id\/(\d*)/i;
var id = id_patt.exec(splat);
id = (id) ? id[1] : null;
//console.log("id is: "+id);
var page_patt = /^page\/(\d*)/i;
var page = page_patt.exec(splat);
}
page = (page) ? page[1] : 1;
//console.log("page is: "+page);
if (id) {
setTimeout('app.play_audio("'+id+'");', 500);
}
setTimeout('app.audio_nav("'+page+'");', 500);
},
audio_nav: function(page) {
var nav_holder = $('#pagination-nav');
if (nav_holder.length == 0) {
app.audio_ondemand('page/'+page);
} else {
var audios = this._audios;
var nav = new AudioNavView({el: nav_holder, audios: audios, page: page});
nav.render();
}
},
play_audio: function(id) {
var audio_holder = $('#audio-player');
if (audio_holder.length == 0) {
app.audio_ondemand('id/'+id);
} else {
var audio = this._audios.getByUid(id);
this._audioview = new AudioView({el: $('#audio-player'), model: audio});
this._audioview.render();
}
}
的觀點並不做什麼特別突出的,但這裏是我的「主人」模板(使用jQuery模板):
<script id="audioOnDemandTmpl" type="text/x-jquery-tmpl">
<div class="sub-header">
<strong>Audio</strong> On Demand
</div>
<div id="currently-playing">
<div id="currently-header">Currently Playing</div>
<div id="current-holder"></div>
</div>
<div id="audio-player"></div>
<div id="pagination-nav"></div>
<div id="audios-holder"></div>
</script>
我想現在你得到的困境承擔。主視圖必須在輔助視圖之前呈現,否則輔助視圖不具有要附加的適當DOM元素。但是,如果我希望次要視圖可路由,則必須執行'hacky'jQuery檢查以查看主視圖是否已呈現。
感謝您的任何想法或建議,並讓我知道如果您需要更多的細節!
UPDATE:因爲它可能有助於更好地給出這個想法,下面是導航視圖和模板。
<script id="audioNavTmpl" type="text/x-jquery-tmpl">
{{if prev > 0}}<a href="#audio_ondemand/page/${prev}">Prev</a> | {{/if}}${current}{{if next}} | <a href="#audio_ondemand/page/${next}">Next</a>{{/if}}
</script>
<script id="audioTmpl" type="text/x-jquery-tmpl">
<div class="audio-holder">
<div class="title-author">
<div class="title"><a href="#audio_ondemand/id/${attributes.uid}">${attributes.title}</a></div>
<div class="author">${attributes.author}</div>
</div>
<div class="topic-date">
<div class="topic"><strong>${attributes.topic}</strong></div>
<div class="date">${attributes.date}</div>
</div>
</div>
</script>
var AudioNavView = Backbone.View.extend({
audioNavTemplate: $('#audioNavTmpl').template(),
audioTemplate: $('#audioTmpl').template(),
initialize: function(options) {
this.audios = options.audios.models;
var temp_page = parseInt(options.page);
this.page = [
{
prev: temp_page - 1,
current: temp_page,
next: temp_page + 1
}
];
this.slice_start = (temp_page - 1) * 11;
this.slice_end = temp_page * 11;
this.audios = this.audios.slice(this.slice_start, this.slice_end);
if (this.audios.length <= 11) {
this.page[0]["next"] = false;
}
},
render: function() {
//console.log(this.page);
this.el.empty();
var sg = this;
$('#audios-holder').fadeOut('fast', function() {
$.tmpl(sg.audioNavTemplate, sg.page).appendTo(sg.el);
$(this).empty();
$.tmpl(sg.audioTemplate, sg.audios).appendTo($(this));
$(this).fadeIn('fast');
});
return this;
}
});
我應該如何更好地設置它,以便如果有人從'#home'直接跳到'#audio_ondemand/page/2',路由器會確保在audioNavView之前加載audioOnDemandView?
「主」視圖和「次要」視圖之間的區別對我而言並不清楚。它們都看起來像可路由的意見。在我看來你的路由器應該有一個跟蹤當前呈現的所有視圖(路由本身是一個理想的關鍵),並路由顯示或構建和顯示視圖。 –
爲導航視圖添加了更多代碼示例,以更好地瞭解發生了什麼。 – Andrew565