【问题标题】:Partial html localisation部分 html 本地化
【发布时间】:2015-05-13 17:03:12
【问题描述】:

问题

我需要本地化我的 Web 应用程序。我使用两种语言 - 英语和挪威语(这不重要)。

我使用资源文件来本地化标准视图。他们位于一个名为 Myproject.Localisation 的单独项目中:

  • Lo​​calized.resx
  • Lo​​calized.no.resx

在剃刀视图中看起来像这样:

<li>@Localised.WhatEverINeedToLocalise</li>

然后我有两个标准的部分 html 文件,其中包含一些 html 和一些 knockout.js,它们像这样作为 amd 依赖项加载并稍后在我的 typescript 类中使用:

///<amd-dependency path="text!./productTemplate.html" />
///<amd-dependency path="text!./anotherTemplate .html" />

var contentTemplate = require("text!./productTemplate.html");
var anotherTemplate = require("text!./anotherTemplate .html");

问题

显然,我也必须在其中进行翻译。有没有办法可以使用 razor 并使用我拥有的资源文件生成这些部分 html 文件?

如果没有,是否还有其他选择,可能比我的解决方案更简单(阅读下文)?


我的解决方案

我想出的唯一方法是安装 i18next 及其敲除绑定,编写一个 T4 模板,该模板将从 resx 文件生成翻译 json,然后使用敲除翻译部分 html。 但是,它似乎过于复杂

【问题讨论】:

  • mvc 中的局部视图呢?你试过了吗?
  • 我在应用程序的管理部分使用了一些局部视图,但它们是在运行时编译的。我还没有尝试过,但我相信如果我直接通过 amd-dependecy 请求 cshtml,它不会被编译,我最终会加载无效代码。但是,我不确定我是否理解正确。这些部分html文件不是我自己写的,现在得自己处理了。
  • 我也找到了这篇文章:afana.me/post/… 但是动态加载静态内容似乎很傻
  • ASP 应该查看它从浏览器获取的标题/语言,并根据您发送的内容更改字符串变量。你确定你用对了吗?
  • 我会尝试,如果它不起作用,会回复你。

标签: asp.net-mvc razor knockout.js typescript requirejs-text


【解决方案1】:

我在我的项目中所做的是使用基本视图模型类来处理来自服务器的文本数据检索。 每个视图模型都有自己的 ID,与服务器上使用的资源 ID 匹配。 获取的文本以如下结构保存在基本视图模型类中:

public texts: KnockoutObservableArray<ITextItem> = ko.observableArray<ITextItem>();

.. ITextItem 是这样的结构:

interface ITextItem {
    id: string;
    value: KnockoutObservable<string>;
}

.. 使用如下函数获取:

public updateTexts(cultId: string): Q.Promise<any> {
    if (this.textsName === '')
        this.textsName = this.modelId;
    if (this.lastCultureIdFetched != cultId) {
        this.lastCultureIdFetched = cultId;
        return mm_cspData.cspCtx.getTexts(this.textsName, this.texts);
    }
    else
        return Q.resolve(true);
}

.. 从视图模型中获取的特定文本如下:

public tx(id: string): string {
    var match: ITextItem = ko.utils.arrayFirst(this.texts(), item=> item.id === id);
    if (!match)
        return ''; 
    else
        return match.value();
}

因此,每次激活视图模型或更改应用程序语言时,都会触发 updateText 方法。

为了在我的 html 视图中显示文本,我使用敲除绑定处理程序从视图模型中获取正确的文本。作为一项规则,每个视图模型都被导出到一个名为 vm 的变量中,所以我可以这样做:

ko.getVmTx = (label: any, bindingContext: any) : string => {
    if (label === null)
        return '';
    var vm: any;
    var labelId;
    if (typeof label === 'object' && typeof label.vm === 'object' && typeof label.vm.tx !== 'function') {
        vm = label.vm;
        labelId = label.tx;
    } else {
        vm = bindingContext.$root.vm;
        labelId = ko.unwrap(label);
    }
    if (vm === null || typeof vm === 'undefined' || typeof vm.tx !== 'function') {
        console.log('tx binding: unable to find vm for ' + label);
        return '';       
    }
    else
    return vm.tx(labelId);
}
ko.bindingHandlers.tx = {
    update: (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) => {
        $(element).text(ko.getVmTx(valueAccessor(),bindingContext));
    }
};
ko.bindingHandlers.txVal = {
    update: (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) => {
        $(element).val(ko.getVmTx(valueAccessor(), bindingContext));
    }
};

最后在我看来,我使用这样的绑定处理程序:

<span class="app-badge-label-bg" data-bind="tx: 'FinInvAmount'"></span>

这是一个庞大的设置,但一旦到位,文本处理由基础视图模型类负责,您需要为每个视图模型做的唯一事情就是在服务器端设置资源文件并使用简单的剔除绑定对您的标签和值进行数据绑定。

【讨论】:

  • 这是相当复杂的方法。如果资源文件很大怎么办?每次语言或上下文更改时加载它们一定是相当大的开销,不是吗?当请求占用大量时间或找不到资源时,向用户显示什么?
  • 无论您采用何种方法,文本都必须加载到浏览器中,无论大小。文本是 html 还是 web 服务有效负载的一部分并不重要。这种方法是基于视图的,因此您只需在加载后获取每个视图的文本。对于每个页面,您通常都会加载一些数据,因此您可能会显示一些加载指示器。 updateTexts 方法返回一个承诺,因此它适合在显示视图页面之前加载数据的模型。
  • 如果没有找到资源,这是一个编程错误,应该在编程或测试阶段发现。但是,如果您想显示错误消息,则可以在响应为空或服务返回异常时将其连接到 updateTexts 消息中。最重要的是,这种方法不会比其他加载应用程序文本的方法花费更长的时间。设置起来很复杂,但是……让程序员在你的应用程序中维护和编写新的视图/视图模型变得非常简单。
  • 如果文本是按视图显示的,那很好。如果每个应用程序有一个文件,则可以在进行一些修改后使用它,可能包括缓存文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多