Подтвердить что ты не робот

Есть ли способ установить заголовок страницы путем привязки данных с помощью Knockout.js?

У меня есть viewModel с свойством Title. Я хотел бы задать заголовок страницы, используя это свойство. Вот то, что я пробовал уже, что не сработало:

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

Заголовок браузера пуст/по умолчанию вместо значения моего свойства Title.

4b9b3361

Ответ 1

Попробуйте указать html-элемент id

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

и применяя к нему свой viewModel

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

ИЗМЕНИТЬ

Это работает для меня; Я просто запустил эту страницу, и название получило название "Привет". Дважды проверьте свой код для опечаток.

<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>

Скриншот:

enter image description here

Ответ 3

В моих глазах эта ситуация требует наблюдаемой подписки.

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

Просмотр модели

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:

Как поправка к моему предыдущему ответу, я хотел бы изложить следующее. Будет ли мое предыдущее предложение работать? Да, это работает очень хорошо. Однако манипуляция DOM в самой модели представления не "точно" соответствует парадигме MVVM. Фактическим "лучшим" подходом было бы создание пользовательской привязки, которая устанавливает заголовок документа для обновления определенного наблюдаемого.

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

Просмотр модели

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();
};

И, наконец, наша блестящая пользовательская привязка для "прослушивания" изменений наблюдаемого (обратите внимание на использование ТОЛЬКО действия обновления)

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;
    }
};

На первый взгляд это решение может показаться менее масштабируемым, но имейте в виду, что мы можем создавать "псевдонаследование" с помощью моделей нокаут-просмотра с помощью "call()".

Ответ 4

Вы можете использовать подписку на нокаут:

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');

Ответ 5

В соответствии с предложением @Douglas моим решением было добавить скрытый div где-то в теле, связанном с вычисленным значением:

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

Затем в вычислении значения я устанавливаю document.title:

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

Это отлично работает для меня