Многоязычное приложение Durandal, заголовок страницы / модуля как наблюдаемый, динамически изменяющийся document.title

Я работаю над локализацией своего дюрандального приложения. Я уже выбрал подход - я использую модуль на всех своих страницах, содержащий все строки, которые может иметь любое представление.

В своей оболочке я определяю

router.map([
    { route: ['', 'search'], title: i18n.search, moduleId: 'viewmodels/search/index', nav: true },
    { route: "employees", title: i18n.employeesList, moduleId: "viewmodels/employees/index", nav: false },
    { route: "details/:id", title: i18n.details, moduleId: "viewmodels/details/index", nav: false }
    // ...
]);

где свойства i18n - это ko.observables, содержащие строки типа

i18n = {
    search: ko.observable("search"),
    employeesList: ko.observable("employeesList"),
    details: ko.observable("Details")
}

Это отлично работает, печатая мою панель навигации с помощью

<ul class = "nav navbar-nav" data-bind = "foreach: router.navigationModel">
    <li data-bind = "css: { active: isActive }">
        <a data-bind = "attr: { href: hash }, text: title"></a>
    </li>
</ul>

однако, когда дело доходит до изменения заголовка документа, это не работает.

Здесь я нашел кое-что о настройке durandal для document.title, к сожалению, ответ предполагает, что для изменения заголовка durandal создает некоторые другие свойства (которые, похоже, основаны на моем свойстве объявления объекта модуля title) и, вероятно, не предполагает, что title может быть чем-то другим, кроме строки.

Есть ли способ переопределить какой-либо метод, который durandal использует для изменения document.title, или любой другой способ заставить его изменять document.title при навигации?


person patryk    schedule 16.10.2013    source источник


Ответы (2)


Вы можете выполнить шаги, описанные в Durandal.js 2.0 Set заголовок документа в методе активации.

Вам нужно будет перезаписать router.updateDocumentTitle в main.js | shell.js, чтобы учесть, что config.title является наблюдаемым.

Что-то вроде следующего должно помочь вам начать.

router.updateDocumentTitle = function(instance, instruction) {
    if (instruction.config.title) {
        if (app.title) {
            document.title = ko.unwrap(instruction.config.title) + " | " + app.title;
        } else {
            document.title = ko.unwrap(instruction.config.title);
        }
    } else if (app.title) {
        document.title = app.title;
    }
};

Обновление: на основе комментария.

В дополнение к модификации, описанной выше, если название должно измениться немедленно, потребуется еще кое-что поработать.

Причина в том, что роутер не знает о переключении языков. Pub / sub, скорее всего, правильный способ реализации. Рассмотрите возможность настройки события, например, с помощью app.on, которое изменяет document.title. router.activeInstruction() предоставит доступ к объекту конфигурации. Запускайте событие всякий раз, когда кто-то переключается на любую модель представления.

person RainerAtSpirit    schedule 16.10.2013
comment
Правда, это сработало. По-прежнему отсутствует возможность обновлять заголовок сразу при переключении языка, но в этом нет необходимости. Спасибо :) - person patryk; 16.10.2013

Это может произойти немного поздно, но я бы тоже хотел добавить свое решение :-) Я использую наблюдаемые, которые изменяют текст моих переменных по запросу. При настройке маршрутов и их параметров следующим образом:

var routes = [{ route: '', title: 'Welcome', moduleId: 'viewmodels/welcome', nav: true, title: 
    ko.computed(function () { return activeTranslation.welcome() }) 
}];

мой activeTranslation выглядит примерно так:

var activeTranslation = {
    welcome: ko.observable()
}

Теперь при смене языка мне просто нужно перебрать свой языковой объект, содержащий те же переменные и их соответствующий перевод, и применить их к наблюдаемому.

var dutch = { welcome: "Welkom" };

function loadLanguage (lang) {
    for (var key in languages[lang]) {
        activeTranslation[key](languages[lang][key]);
    }
}
person Sander Teunissen    schedule 06.06.2014
comment
Работает ли это с title свойствами как ko.computed() наблюдаемыми? Жаль, что я не пришел к этому один, потому что это, кажется, хорошее решение в моем случае. Спасибо за уделенное время :) - person patryk; 06.06.2014
comment
@patryk: Это не твоя вина, просто очень плохой момент. Я отправил им патч для этого ровно через день после того, как вы задали здесь свой вопрос (бессознательно), и они объединил его в феврале '14. Вы не могли этого увидеть. - person tne; 02.07.2015
comment
Несмотря на то, что этот вопрос устарел, спасибо за информацию. Я уже давно не использую ни дюрандал, ни нокаут, но все же спасибо @tne! - person patryk; 02.07.2015