2012-05-07 14 views
16

Sto creando un'applicazione a singola pagina con backbone.js e vorrei conoscere il modo migliore per gestire la modifica del titolo. Stavo pensando di avere un'opzione 'titolo' nella vista e di avere il router (in qualche modo) impostare il documento.titolo. Qualcuno ha implementato qualcosa di simile? GrazieBackbone e document.title

+1

Perché è necessario un 'View.title'? .. Penso che Vista non dovrebbe essere correlato al' page.title', penso che il 'Router' stesso debba sovrascrivere il' document.title' senza infastidire qualsiasi altro componente della tua applicazione. – fguillen

+0

Questo è il modo in cui lo ho al momento, volevo solo evitare il codice ripetitivo nel router. Penso di legare una funzione nel router che ottiene il titolo di una vista e la imposta come document.title senza dover ripetere la linea con ciascuna rotta – Xerri

risposta

33

perché non utilizzare la natura evented di Backbone.js.

Prima di tutto non penso che dipenda dal router delegare l'aggiornamento del titolo del documento. Soprattutto se lavori con applicazioni client-side più grandi, vuoi mantenerlo semplice e assicurarti che ogni parte della tua applicazione soddisfi un compito specifico.

Il router è lì per delegare percorsi, niente di più.

Quello che suggerirei invece è (a seconda di come si inizializza l'applicazione) per creare un aggregatore di eventi a livello di applicazione.

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

e legare un evento per la vostra applicazione, come ad esempio:

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

dove nell'applicazione costruire

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

e ora, invece di dover lasciarlo fino al Router a prendi sempre il titolo e assicurati che ci sia il metodo getTitle in ogni vista, puoi - all'interno della tua vista e quindi QUALSIASI vista - attivare il seguente evento quando esegui il rendering o l'inizializzazione della vista:

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

a mio parere è un codice più pulito e più snello, ma ripeto, è solo un parere.

+1

Anche questa è una soluzione interessante. Avevo immaginato i casi (dopo averli costruiti) dove la Vista è "attivata", non inizializzata o ri-resa (forse per esempio è appena nascosta). Quindi, dovrei aggiungere una funzione/evento "attivato" da attivare. Inoltre, a causa della composizione, non ero sicuro che una vista dovesse sapere come si inserisce nell'immagine più grande (forse non dovrebbe essere permesso di attivare la modifica del titolo in questo momento, ecc.). Tuttavia, mi piace lo schema. – WiredPrairie

+2

Rivisitato e implementato una variabile globale per l'applicazione. In esso immagazzino un aggregatore di eventi. Un evento verrà attivato dalla vista e l'aggregatore cambierà il titolo del documento. Come nota a margine, è possibile creare un evento sul router per ascoltare le eventuali modifiche al percorso. Questo può forse innescare il cambiamento di document.title. http://stackoverflow.com/a/9521144 – Xerri

2

Suggerisco di inserire il codice nei callback del router. Sarà un'altra riga di codice, ma senza la conoscenza della vista corrente, il router/app non sapranno quale vista ha il titolo corretto. (Non c'è davvero un buon posto per sovrascrivere il comportamento e fornire un titolo del documento senza sostituire alcune funzioni incorporate in Backbone.JS).

si potrebbe aggiungere qualcosa al tuo punto di vista molto semplice:

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

E poi nella vostra richiamata router:

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

Un'altra opzione sarebbe quella di solo avere la vista impostarlo quando viene creato o quando viene chiamato un metodo speciale. Ma, userei la prima opzione.

27

Perché stai utilizzando jQuery per modificare il titolo del documento utilizzando puro Javascript? Più veloce, più facile, più pulito ...

document.title = 'new title'; 
+16

... sei serio? Dai, questa è la cosa più stupida che abbia mai sentito. jQuery è costruito su JS puro e, in effetti, jQuery è un framework per costruire cose con puro JS. Quindi, qual è il problema usando puro JS ??? – miduga

+0

Questo è tutto corretto (ovviamente jquery è costruito usando js puri!), Ma non quello che ho detto, sarà sempre più pulito se ti attacchi a uno o l'altro ogni volta che puoi. –

+9

la gente si appoggia troppo a jQuery. al punto in cui le persone che si definiscono 'sviluppatori js' non riescono a ricordare come manipolare DOM con JavaScript nativo –

1

Questo è quello che faccio questo mio progetto:

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

Kinda molto vecchio post, ma io darò ancora una reincarnazione.


Con corrente Marionette v3.2.0 è possibile effettuare le seguenti operazioni:

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

Secondo lei si crea quel metodo magico come questo:

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

E risoluzione titolo stesso possono essere i seguenti :

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

Consente risoluzione di titoli restituita come array e implode da un singolo separatore di

  • Può essere facilmente integrato nel flusso di lavoro applicazione al posto in cui gestire i tuoi programmi di contenuto.
  • onPageTitle verrà chiamato nel contesto di visualizzazione (this sarà l'istanza di visualizzazione all'interno della funzione), ciò che dà la possibilità di richiamare i dati del modello e qualsiasi materiale relativo alla vista.
  • Non c'è bisogno di preoccuparsi di controllare la disponibilità del metodo, basta chiamare e andare.
  • Inoltre, è sempre possibile eseguire il fallback del titolo predefinito se non viene definito un tale metodo come triggerMethod restituirà undefined in questi casi.
  • Utile!
+0

Grazie per il tuo contributo, ma passato ad Angular da questo post. – Xerri