Durandal多语言应用程序,页面/模块标题作为可观察,动态更改document.title

时间:2013-10-16 11:31:49

标签: javascript router durandal

我正致力于本地化我的durandal应用程序。我已经选择了一种方法 - 我在所有页面上共享一个模块,其中包含任何视图可能具有的所有字符串。

在我的shell中,我正在定义

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>

然而,当涉及到更改文档标题时,它不起作用。

Here我找到了关于durandal设置document.title的一些内容,不幸的是,答案表明改变标题durandal会创建一些其他属性(这似乎是基于我的title模块对象声明属性并且可能不假设title可能不是字符串。

有没有办法覆盖durandal用于更改document.title或其他任何方法的方法,以便在导航时更改document.title?

2 个答案:

答案 0 :(得分:4)

您可以按照Durandal.js 2.0 Set document title within activate method中列出的步骤进行操作。

您需要覆盖main.js | shell.js中的router.updateDocumentTitle,以便考虑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()将提供对配置对象的访问权限。只要有人切换到任何视图模型,就会触发事件。

答案 1 :(得分:2)

这可能会有点晚,但我也想添加我的解决方案:-) 我正在使用observables,它可以根据需要更改变量的文本。 设置路线及其选项时如下:

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

我的activeTranslation看起来像这样:

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

现在,在更改语言时,我只需要遍历包含相同变量及其各自翻译的语言对象,并将它们应用于observable。

var dutch = { welcome: "Welkom" };

function loadLanguage (lang) {
    for (var key in languages[lang]) {
        activeTranslation[key](languages[lang][key]);
    }
}