2012-05-07 25 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