2012-05-07 8 views
16

Estoy creando una aplicación de una sola página con backbone.js y me gustaría saber la mejor manera de manejar el cambio del título. Estaba pensando en tener una opción de 'título' en la vista y hacer que el enrutador (de alguna manera) establezca document.title. ¿Alguien ha implementado algo similar? GraciasBackbone y document.title

+1

¿Por qué necesita un 'View.title'? ... Creo que View no debe estar relacionado con' page.title', creo que el 'Router' en sí debe sobrescribir' document.title' sin moleste a cualquier otro componente de su aplicación. – fguillen

+0

Esa es la forma en que lo tengo en este momento, solo quería evitar el código repetitivo en el enrutador. Estoy pensando enlazar una función en el enrutador que obtiene el título de una vista y lo establece como document.title sin tener que repetir la línea con cada ruta – Xerri

Respuesta

33

por qué no utilizar la naturaleza evented de Backbone.js.

En primer lugar, no creo que corresponda al enrutador delegar la actualización del título del documento. Especialmente si está trabajando con aplicaciones más grandes del lado del cliente, quiere mantenerlo simple y asegurarse de que cada parte de su aplicación cumpla una tarea específica.

El enrutador está ahí para delegar rutas, nada más.

lo que sugeriría en su lugar es (dependiendo de cómo inicialice su aplicación) para crear un agregador de eventos a nivel de aplicación.

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

y enlazar un evento para su aplicación como tal:

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

donde en su Solicitud de construir

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

y ahora, en lugar de tener que dejarlo hasta que el router Siempre tome el título y asegúrese de que haya un método getTitle en cada vista; puede, dentro de su vista y, por lo tanto, CUALQUIER vista, activar el siguiente evento cuando represente o inicialice la vista:

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

hace que el código sea más limpio y simple en mi opinión, pero de nuevo, eso es solo una opinión.

+1

Esa es una solución interesante también. Me imaginé casos (habiéndolos construido) donde la Vista está "activada", no inicializada o re-renderizada (tal vez, por ejemplo, simplemente está oculta). Entonces, necesitaría agregar una función/evento "activado" para disparar. Además, debido a la composición, no estaba seguro de si una Vista debería saber cómo encaja en la imagen más grande (quizás no debería permitirse activar el cambio de título en este momento, etc.). No obstante, me gusta el patrón. – WiredPrairie

+2

Revisado esto e implementado una variable global para la aplicación. En él guardo un agregador de eventos. La vista activará un evento y el agregador cambiará el título del documento. Como nota al margen, se puede crear un evento en el enrutador para escuchar cualquier cambio de ruta. Esto puede provocar un cambio de document.title. http://stackoverflow.com/a/9521144 – Xerri

2

Le sugiero que simplemente coloque el código en las devoluciones de llamada de su enrutador. Será otra línea de código, pero sin conocimiento de la vista actual, el enrutador/aplicación no sabrá qué vista tiene el título correcto. (Realmente no hay un buen lugar para anular el comportamiento y proporcionar un título del documento sin reemplazar algunas funciones integradas en Backbone.JS).

Se podría añadir algo a su punto de vista muy simple:

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

Y luego en su devolución de llamada enrutador:

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

Otra opción sería la de simplemente tener la vista configurarlo cuando se crea o cuando se llama un método especial. Pero, utilizaría la primera opción.

27

¿Por qué todos ustedes usan jQuery para cambiar el título del documento en lugar de usar Javascript puro? Más rápido, más fácil, más limpio ...

document.title = 'new title'; 
+16

... ¿Hablas en serio? Vamos, esa es la cosa más estúpida que escuché jamás. jQuery está basado en JS puro y, de hecho, jQuery es un framework para construir cosas con JS puro. Entonces, ¿cuál es el problema con JS puro? – miduga

+0

Eso es todo correcto (¡por supuesto jquery está construido usando js puro!), Pero no es lo que dije, siempre se verá más limpio si te apegas a uno u otro siempre que puedas. –

+9

las personas se apoyan demasiado en jQuery. hasta el punto en que las personas que se llaman a sí mismas 'desarrolladores de js' no pueden recordar cómo hacer la manipulación de DOM con JavaScript nativo –

1

Esto es lo que hago mi proyecto:

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

Un poco muy antiguo puesto, pero lo voy a dar una reencarnación más.


con corriente Marionette v3.2.0 puede hacer lo siguiente:

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

En su opinión usted la creación de ese método mágico como esto:

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

y una resolución del título en sí mismo puede ser el siguiente :

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

permite la resolución de títulos devuelve como matrices y implosiona por un único separador

  • Se puede integrar fácilmente en el flujo de trabajo de aplicación en el lugar donde puede gestionar sus programas de contenido.
  • onPageTitle serán llamados en el contexto de vista (this será la instancia de vista dentro de la función), lo que da la posibilidad de invocar datos de modelo y cualquier material relacionado vista.
  • No hay necesidad de molestarse con verificar la disponibilidad del método, solo llame y listo.
  • Por otra parte, siempre puede recurrir a título predeterminado si no se define tal método como triggerMethod devolverá undefined en tales casos.
  • ¡Ganar!
+0

Gracias por su entrada pero cambió a Angular desde esta publicación. – Xerri