简单的解决方案
因为我真的不喜欢它,所以有可能从 url 参数检测 i18next 的语言。在 i18next 选项中,您需要添加以下条目:
detectLngQS: 'lang'
多亏了它您可以使用?lang=en-US
url 参数设置页面语言。
更好的(恕我直言)解决方案
在我的应用程序中,我曾经创建处理 Durandal 本地化功能的本地化服务模块。在App/services
我确实使用以下代码创建localization.ts
文件(对不起,TypeScript,但我真的更喜欢它而不是 JS):
/// <reference path='../../Scripts/typings/durandal/durandal.d.ts' />
/// <reference path='../../Scripts/typings/i18next/i18next.d.ts' />
//#region Imports
import app = require('durandal/app');
//#endregion
//#region Public Members
export var Languages: KnockoutObservableArray<ILanguage> = ko.observableArray();
export var Init = (callback: (t: (key: string, options?: any) => string) => void) =>
{
var pl: ILanguage =
{
Id: ko.observable('pl'),
Name: ko.observable('Polski'),
Icon: ko.observable('Content/images/pl_flag.png'),
IsActive: ko.observable(true)
};
var en: ILanguage =
{
Id: ko.observable('en'),
Name: ko.observable('English'),
Icon: ko.observable('Content/images/en_flag.png'),
IsActive: ko.observable(false)
};
var de: ILanguage =
{
Id: ko.observable('de'),
Name: ko.observable('German'),
Icon: ko.observable('Content/images/de_flag.png'),
IsActive: ko.observable(false)
};
Languages.push(pl);
Languages.push(en);
Languages.push(de);
var option: I18nextOptions =
{
preload: ['pl', 'en', 'de'],
lng: 'pl',
fallbackLng: 'pl',
ns: 'app',
debug: true
};
$.i18n.init(option, callback);
app.trigger('Localization:Init');
};
export var T = (key: string) =>
{
return $.i18n.t(key);
};
export var Lng = () =>
{
return $.i18n.lng();
};
export var SetLng = (lng: ILanguage) =>
{
for (var l in Languages())
{
var value = Languages()[l];
if (value.Id != lng.Id)
{
value.IsActive(false);
}
else
{
value.IsActive(true);
}
}
$.i18n.setLng(lng.Id());
$('*').i18n();
app.trigger('Localization:SetLng');
};
//#endregion
//#region Local Interfaces
export interface ILanguage
{
Id: KnockoutObservable<string>;
Name: KnockoutObservable<string>;
Icon: KnockoutObservable<string>;
IsActive: KnockoutObservable<boolean>;
}
//#endregion
main.js
在回调的文件中调用初始化函数app.start()
:
app.start().then(function () {
toastr.options.positionClass = 'toast-bottom-right';
toastr.options.backgroundpositionClass = 'toast-bottom-right';
viewLocator.useConvention();
localization.Init(function () {
binder.binding = function (obj, view) {
$(view).i18n();
};
app.setRoot('viewmodels/shell', 'entrance');
});
});
值得注意的是,Init 函数是一些复杂的本地化初始化(例如从数据库获取本地化选项)的好地方。
对你来说最重要的是SetLng
。根据您的架构和想法,它可以在许多地方调用,但由于它在模块中,因此可以在任何其他模块中调用(仅由 require.js 引用),所以它很棒。我通常在引导导航栏中创建本地化按钮,这让我可以随时更改语言。
编辑
据我所知,您仍然可以将 i18next 用于 MVC 视图 - 只需设置 i18next 绑定。如果您想根据身份验证设置语言,最好的选择可能是使用 18next cookie。在您的登录 MVC 操作中,您需要添加类似于以下内容的内容:
var languageCode = GetLanguageCode(username)
var userCookie = new HttpCookie("i18next", languageCode );
userCookie.Expires.AddDays(365);
HttpContext.Response.Cookies.Add(userCookie);
只需确保 i18next 选项中的默认设置为英语 - 将为匿名用户选择此语言。登录后语言将根据您的逻辑设置,选择将保存在 cookie 中
编辑 2
它应该只是 text.js 文件中的微小变化 - 可能您应该在 273 之前只添加两三行。 text.js 行(和一个辅助函数)
首先,我们需要帮助函数来获取给定 cookie 的值( document.cookie 返回所有 cookie 名称和连接的值,因此我们需要以某种方式解析它)
function getCookie(cname)
{
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++)
{
var c = ca[i].trim();
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
}
return "";
}
现在你需要修改你的 text.js 文件来设置 i18next cookie。273.之前的代码行:
var cookie = getCookie('i18next');
if ( cookie != '') xhr.setRequestHeader("Cookie", "i18next=" + cookie);