2012-05-07 6 views
16

Tworzę aplikację z pojedynczą stroną z backbone.js i chciałbym wiedzieć, jak najlepiej radzić sobie ze zmianą tytułu. Myślałem o opcji "tytuł" w widoku i router (jakoś) ustawić plik document.title. Czy ktoś wdrożył coś podobnego? DziękiKręgosłup i document.title

+1

Dlaczego potrzebujesz 'View.title'? .. Myślę, że View nie powinien być związany z' page.title', myślę, że 'Router' powinien sam nadpisać' document.title' przeszkadzać innym komponentom aplikacji. – fguillen

+0

To jest sposób, w jaki mam to w tej chwili, po prostu chciałem uniknąć powtarzalnego kodu w routerze. Zastanawiam się nad powiązaniem funkcji routera, który otrzymuje tytuł widoku i ustawia go jako document.title bez powtarzania linii z każdą trasą. – Xerri

Odpowiedz

33

dlaczego nie używać zdarzenia Backbone.js.

Po pierwsze, nie sądzę, że to router musi delegować aktualizację tytułu dokumentu. Szczególnie, jeśli pracujesz z większymi aplikacjami po stronie klienta, chcesz zachować prostotę i upewnić się, że każda część aplikacji spełnia określone zadanie.

Router umożliwia delegowanie tras, nic więcej.

Proponuję zamiast tego (w zależności od sposobu zainicjowania aplikacji) utworzenie agregatora zdarzeń na poziomie aplikacji.

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

i powiązać zdarzenie do aplikacji jako takie:

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

gdzie w aplikacji budowę

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

i teraz, zamiast pozostawić go do routera, aby zawsze chwytaj tytuł i upewnij się, że w każdym widoku istnieje metoda getTitle, możesz - wewnątrz widoku i dlatego DOWOLNY widok - wywołać następujące zdarzenie podczas renderowania lub inicjowania widoku:

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

to, moim zdaniem, czystszy i szczuplejszy kod, ale z drugiej strony to tylko opinia.

+1

To także ciekawe rozwiązanie. Wyobrażałem sobie przypadki (po ich zbudowaniu), w których Widok jest "aktywowany", niezainicjowany lub ponownie renderowany (może na przykład po prostu ukryty). Musiałbym więc dodać "aktywowaną" funkcję/zdarzenie do uruchomienia. Ponadto, ze względu na kompozycję, nie byłem pewien, czy View powinien wiedzieć, w jaki sposób pasuje do większego obrazu (może to nie powinno teraz pozwolić na zmianę tytułu, itp.). Niemniej jednak podoba mi się wzór. – WiredPrairie

+2

Ponownie sprawdzono to i zaimplementowano zmienną globalną dla aplikacji. W nim przechowuję agregator zdarzeń. Zdarzenie zostanie wywołane przez widok, a agregator zmieni tytuł dokumentu. Na marginesie można utworzyć na routerze zdarzenie, aby posłuchać każdej zmiany trasy. Może to być przyczyną zmiany w dokumencie document.title. http://stackoverflow.com/a/9521144 – Xerri

2

Proponuję po prostu umieszczenie kodu w wywołaniach zwrotnych routera. Będzie to kolejna linia kodu, ale bez znajomości bieżącego widoku router/aplikacja nie będzie wiedział, który widok ma poprawny tytuł. (Naprawdę nie ma dobrego miejsca na zastąpienie tego zachowania i podanie tytułu dokumentu bez zastępowania niektórych wbudowanych funkcji w Backbone.JS).

Można dodać coś do widzenia bardzo prosto:

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

A potem w routerze zwrotnego:

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

Innym rozwiązaniem byłoby po prostu mają widok ustawić go, gdy jest tworzony lub gdy wywoływana jest specjalna metoda. Ale użyłbym pierwszej opcji.

27

Dlaczego wszyscy używają jQuery do zmiany tytułu dokumentu zamiast używania czystego kodu JavaScript? Szybciej, łatwiej, czyściej ...

document.title = 'new title'; 
+16

... jesteś poważny? No dalej, to najgłupsza rzecz, jaką kiedykolwiek słyszałem. jQuery jest zbudowany na czystym JS i w rzeczywistości jQuery to framework do budowania rzeczy z czystym JS. Więc jaki jest problem z czystym JS ??? – miduga

+0

To wszystko jest poprawne (oczywiście jquery jest zbudowane przy użyciu czystego js!), Ale nie to, co powiedziałem, zawsze będzie wyglądać czysto, jeśli trzymasz się jednego lub drugiego, kiedy tylko możesz. –

+9

ludzie opierają się na jQuery za dużo. do punktu, w którym ludzie, którzy nazywają siebie "programistami js", nie pamiętają, jak manipulować DOMem z natywnym JavaScriptem –

1

To co robię to mój projekt:

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 bardzo stary post, ale dam mu jeszcze jedną reinkarnację.


Przy obecnym Marionette v3.2.0 można wykonać następujące czynności:

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

W widoku tworzeni że magiczna metoda tak:

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

i rozdzielczości tytuł może sama być następujące :

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

Pozwala rozdzielczości tytułów zwracane jako tablic i implodes pojedynczym separatorem

  • może być łatwo zintegrowany przepływ pracy aplikacji w miejscu, gdzie zarządzać pokazy treści.
  • onPageTitle będzie wywoływany w kontekście widoku (this będzie instancją widoku wewnątrz funkcji), co daje możliwość wywołania danych modelu i wszelkich związanych z nimi rzeczy.
  • Nie musisz się martwić sprawdzaniem dostępności metod, po prostu zadzwoń i idź.
  • Co więcej, zawsze można powrócić do tytułu domyślnego, jeśli taka metoda nie jest zdefiniowana jako triggerMethod w takich przypadkach zwróci undefined.
  • Zysk!
+0

Dziękujemy za dane wejściowe, ale zmieniliśmy na Angular od tego wpisu. – Xerri

Powiązane problemy