1

問題

Web アプリケーションをローカライズする必要があります。私は英語とノルウェー語の 2 つの言語を使用しています (それは問題ではありません)。

リソース ファイルを使用して標準ビューをローカライズします。これらは、Myproject.Localisation という別のプロジェクトにあります。

  • ローカライズされた.resx
  • Localized.no.resx

カミソリビューでは次のようになります。

<li>@Localised.WhatEverINeedToLocalise</li>

次に、いくつかの html といくつかの knockout.js を含む 2 つの標準の部分的な html ファイルがあり、これらはこのような 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");

質問

明らかに、それらの翻訳も行う必要があります。かみそりを使用して、私が持っているリソース ファイルを使用して、これらの部分的な html ファイルを生成する方法はありますか?

そうでない場合、おそらく私の解決策よりも簡単な他のオプションはありますか(以下を読んでください)?


私の解決策

私が思いついた唯一の方法は、i18next とそのノックアウト バインディングをインストールし、resx ファイルから翻訳 json を生成する T4 テンプレートを作成し、ノックアウトを使用して部分的な html を翻訳することでした。ただし、かなり複雑すぎるようです。

4

1 に答える 1

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>

これは大規模なセットアップですが、一度配置すると、テキスト処理は基本ビューモデル クラスによって処理され、各ビューモデルに対して行う必要があるのは、サーバー側でリソース ファイルをセットアップしてデータ バインドすることだけです。シンプルなノックアウト バインディングでラベルと値を作成します。

于 2015-04-19T00:25:30.970 に答える