2012-05-07 56 views
16

我正在用backbone.js創建一個單獨的頁面應用程序,並希望知道處理改變標題的最佳方式。我正在考慮在視圖中使用「標題」選項,並讓路由器(以某種方式)設置document.title。有沒有人執行過類似的事 謝謝Backbone and document.title

+1

爲什麼你需要一個'View.title'?..我認爲View不應該與'page.title'有關,我認爲'Router'本身應該覆蓋'document.title'而沒有打擾您的應用程序的任何其他組件。 – fguillen

+0

這是我目前的方式,只是想避免路由器中的重複代碼。我想在路由器中綁定一個獲取視圖標題的函數,並將其設置爲document.title,而不必在每條路線上重複該行 – Xerri

回答

33

爲什麼不使用Backbone.js的均衡性質。

首先我不認爲這是由路由器委派更新文檔標題。特別是如果您正在處理更大的客戶端應用程序,您希望保持簡單並確保應用程序的每個部分都能完成特定的任務。

路由器在那裏委託路由,僅此而已。

我建議改爲(取決於初始化應用程序的方式)來創建應用程序級事件聚合器。

var app = new Application(); 
app.eventAggregator = _.extend({}, Backbone.Events); 

,並結合這樣一個事件,您的應用程序:

app.eventAggregator.on('domchange:title', this.onDomChangeTitle, this); 

凡在你的應用程序構建,而不必離開它的路由器

onDomChangeTitle: function (title) 
{ 
    $(document).attr('title', title); 
} 

現在,總是抓住標題並確保在每個視圖中有getTitle方法,您可以 - 在視圖內,因此,任何視圖 - 在渲染或初始化視圖時觸發以下事件:

app.eventAggregator.trigger('domchange:title', this.title); 

它使我認爲更清潔和更精簡的代碼,但是再次,這只是一個意見。

+1

這也是一個有趣的解決方案。我想象的情況下(建立他們)視圖是「激活」,沒有初始化或重新渲染(也許例如它只是隱藏)。所以,我需要添加一個「激活」的功能/事件來觸發。另外,由於構圖的原因,我不確定View是否應該知道它如何適合更大的圖片(也許它不應該被允許立即觸發標題更改等)。儘管如此,我喜歡這種模式。 – WiredPrairie

+2

重新訪問這個併爲應用程序實現了一個全局變量。其中我存儲了一個事件聚合器。視圖將觸發事件,聚合器將更改文檔標題。作爲附註,可以在路由器上創建一個事件來監聽任何路由變化。這可能會觸發document.title更改。 http://stackoverflow.com/a/9521144 – Xerri

2

我建議你把代碼放在你的路由器回調中。它將是另一行代碼,但在不瞭解當前視圖的情況下,路由器/應用程序將不知道哪個視圖具有正確的標題。 (真的沒有一個好的地方可以覆蓋這個行爲,並提供一個文檔標題而不需要替換Backbone.JS中的某些內置函數)。

你可以講一下你的觀點很簡單:

var PeopleView = Backbone.View.extend({ 
    title: 'People are People', 
    // 
    //or 
    // 
    getTitle: function() { 
     return "Something Dynamic"; 
    } 
}); 

然後在你的路由器的回調:

var v = new PeopleView(); 
$(document).attr('title', v.getTitle()); 

另外一個選擇是隻具有View設置在創建時或者當調用特殊方法時。但是,我會使用第一個選項。

27

爲什麼你們都使用jQuery來改變文檔的標題,而不是使用純Javascript?更快,更方便,更清潔......

document.title = 'new title'; 
+16

...你認真嗎?來吧,這是我聽過的最愚蠢的事情。 jQuery建立在純JS上,事實上,jQuery是一個用純JS構建東西的框架。那麼,使用純JS的問題是什麼? – miduga

+0

這一切都是正確的(當然jquery是使用純js構建的!),但並非我所說的,如果你堅持使用其中的一種,它總是會看起來更乾淨。 –

+9

人依靠jQuery太多。到現在自稱爲'js開發人員'的人無法回想如何使用本地JavaScript進行DOM操作 –

1

這是我做這個我的項目:

var App = {}; 

App.HomeView = Backbone.View.extend({ 
    documentTitle: 'my site title' 
}) 
var Router = Backbone.Router.extend({ 
    routes: { 
     '': 'home' 
    , 'home': 'home' 

, baseTitle: ' - my site' 

, home: function(actions) { 
    var obj = this; 
    obj._changePage('HomeView'); 
    } 

, changeTitle: function(title, withoutBaseTitle) { 
    var obj = this; 

    if(withoutBaseTitle !== true) 
     title += obj.baseTitle; 

    document.title = title; 
    return obj; 
    } 

, _changePage: function(viewName, viewOptions) { 
    var obj = this; 
    var page = App[viewName](); 

    if(typeof page.documentTitle !== 'undefined') { 
     obj.changeTitle(page.documentTitle); 
    } 
    } 

}) 
1

均田很老的文章,但我給它多了一個輪迴。


隨着當前Marionette v3.2.0你可以做到以下幾點:

// Get title from view where we manage our layout/views 
var viewTitle = view.triggerMethod('page:title'); 

在你看來,你創造神奇的方法是這樣的:

Mn.View.extend({ 
    onPageTitle() { 
     return ['User', this.model.get('id')].join(' | '); 
    } 
}); 

和標題決議本身可以是以下:

document.title = !!viewTitle 
     ? (
      _.isArray(viewTitle) 
       ? [baseTitle].concat(viewTitle) 
       : [baseTitle, viewTitle] 
     ).join('/') 
     : baseTitle ; 

允許職稱的分辨率由單個分離

  • 它可以方便地集成到應用程序的工作流程中的地方,你管理你的內容顯示返回數組和內爆。
  • onPageTitle將在視圖上下文(this將是功能內的視圖實例)被調用,是什麼給調用模型數據和任何視圖相關的東西的可能性。
  • 無需打擾檢查方法的可用性,只需撥打電話即可。
  • 此外,如果沒有定義此類方法,那麼您總是可以回退到默認標題。在這種情況下,triggerMethod將返回undefined
  • 利潤!
+0

感謝您的意見,但自從這篇文章轉向Angular。 – Xerri