2011-12-27 5 views
22

Mam viewModel z właściwością Title. Chciałbym ustawić tytuł strony za pomocą tej właściwości. Oto, co już próbowałem, który nie działa:Czy istnieje sposób ustawienia tytułu strony przez powiązanie danych za pomocą Knockout.js?

<html> 
    <head> 
    <title data-bind="text: Title"></title> 
</head> 
<body> 
    <span data-bind="text: Title"/> <!-- this displays the title properly --> 
</body> 

Tytuł przeglądarki jest puste/default zamiast wartości mojego Title nieruchomości.

+0

Nie chcę zachować edycji moją odpowiedź - jakaś szansa na to oddanie swoich prac tagu HTML? '' –

+0

Czy możesz powiązać właściwość Title w swoim ViewModel z czymś bardziej przyziemnym, na przykład rozpiętością, i czy wszystko jest w porządku? –

+0

Zaktualizowałem trochę mój kod. Tak, mogę powiązać z danymi "Tytuł" w innych miejscach z powodzeniem. To tylko tytuł strony, który nie działa. –

Odpowiedz

19

Spróbuj dając elemencie html id

<html id="htmlTop" xmlns="http://www.w3.org/1999/xhtml"> 

i stosując swoją ViewModel do niego

ko.applyBindings(viewModel, document.getElementById("htmlTop")); 

EDYCJA

To działa na mnie; Właśnie uruchomiłem tę stronę, a tytuł powiedział "Cześć". Sprawdź dwukrotnie swój kod pod kątem literówek.

<html id="htmlTop"> 

    <head> 
     <title data-bind="text: title"></title> 

     <script type='text/javascript' src='jquery.min.js'></script> 
     <script type='text/javascript' src='knockout-1.2.1.js'></script> 

     <script type="text/javascript"> 

      $(function() { 
       var viewModel = { title: "Hello" }; 
       ko.applyBindings(viewModel, document.getElementById("htmlTop")); 
      }); 

     </script> 

    </head> 

    <body> 
    </body> 
</html> 

Zrzut ekranu:

enter image description here

+0

Próbowałem tego, ale bez zmian. –

+0

@Byron - przepraszam - mam jeszcze jeden pomysł, wtedy myślę, że zbiornik będzie suchy :) --- zobacz edytuj –

+0

@ByronSommardahl Co powiesz na przekazanie elementu HTML zamiast samego dokumentu? Coś jak "document.getElementsByTagName (" html ")'. –

3

Można by stworzyć custom binding handler który ustawia document.title na aktualizację, następnie dodać wiązanie do elementu body.

+0

Czy widziałeś już tę pracę lub możesz zamieścić przykład? –

+0

Spójrz na ostatni przykład na stronie, do której dołączyłem powyżej, hasFocus one. Byłoby bardzo podobnie, z wyjątkiem, że nie potrzebowałbyś 'init', a' update' ustawił 'document.title' na' ko.utils.unwrapObservable (value) 'zamiast używać go w' if ' 'blok. – Douglas

0

Zgodnie @ sugestią Douglasa, moje rozwiązanie było dodać ukrytą div gdzieś w organizmie związany wartość wyliczona:

<div data-bind="text: currentPageTitle()"></div> 

Następnie, przy obliczaniu wartości, ustawić document.title:

self.currentPageTitle = ko.computed(function() { 
    document.title = self.Title(); 
    return self.Title(); 
}, this); 

działa to doskonale dla mnie

2

w moich oczach, to sytuacje błaga o obserwowanej subskrypcji.

... 
<title>{FALL BACK TEXT}</title> 
... 

Widok Model

ViewModel = function() { 
    var self = this; 
    self.PageTitle = ko.observable(null); 
    self.PageTitle.subscribe(function(newValue){ document.title = self.PageTitle() }); 

    //change PageTitle to see your handy work in action 
    self.PageTitle("Hello World!"); 

}; 

EDIT:

jako poprawka do mojej poprzedniej odpowiedzi, chciałbym wysunąć następujące. Czy moja poprzednia sugestia zadziała? Tak, działa bardzo ładnie. Jednak manipulacja DOM w samym modelu widoku nie "dokładnie" postępuje zgodnie z paradygmatem MVVM. Rzeczywistym "najlepszym" podejściem byłoby stworzenie niestandardowego powiązania, które ustawia tytuł dokumentu na aktualizację konkretnego obserwowalnego.

... 
<title data-bind="htmlDocumentTitle: PageTitle()">{FALLBACK TEXT}</title> 
... 

Widok Model

ViewModel = function() { 
    var self = this; 
    self.PageTitle = ko.observable(null); 

    self.init = function(){ 
     self.PageTitle("My page title from an obersvable"); 
    }; 

    //init the viewmodel 
    self.init(); 
}; 

I wreszcie nasze błyszczące wiążący "słuchać" zmian do zaobserwowania (uwaga użycie wyłącznie działaniem update)

ko.bindingHandlers.htmlDocumentTitle = { 
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { 
     var fallbackTitle = "My document title"; 
     var title = ko.unwrap(valueAccessor()); 

     if(!title || title == null && title == "") 
      title = fallbackTitle; 

     document.title = title; 
    } 
}; 

Początkowo zwyczaj Wygląda na to, że to rozwiązanie może wyglądać na mniej skalowalne, ale pamiętaj, że możemy tworzyć "pseudo-dziedziczenie" za pomocą Knockout View Models za pomocą "call()".

+2

Pracowałem dla mnie! Jest to szczególnie przydatny sposób postępowania, gdy nie chcesz zanieczyszczać nagłówka strony znacznikami KO, które będą używane dynamicznie tylko w kilku szczególnych przypadkach. –

1

Można użyć nokaut subskrybować:

function viewModel() { 
    var self = this; 

    self.title = ko.observable(null); 
    self.title.subscribe(function(newTitle) { 
     document.title = newTitle; 
    }) 
} 

var vm = new viewModel(); 
ko.applyBindings(vm); 

vm.title('Hello page'); 
Powiązane problemy