web-dev-qa-db-ja.com

Angular国際化へのデータベースアプローチをどのように実装できますか?

Angular i8nガイドはこちら: https://angular.io/guide/i18n を読みました

ファイルのマークアップとヒントを使用して、コンセプトが気に入っています。

テキストリソースが奇妙なファイル形式のままであり、一度翻訳するのは簡単ですが、外部から維持するのが非常に難しいのが嫌です。

Angularはi8nをサポートしていますが、静的テキストファイルをデータベースへの呼び出し、またはデータベースによって生成されたjsonファイルのようなものに置き換えるのに、かなり簡単な方法はありますか?

17
Kjensen

databaseから翻訳をロードする際の ngx-translate の使用を含む、i18nを扱う私のアプローチは次のとおりです。

翻訳に関しては、私のバックエンドとフロントエンドが分かれています。翻訳はangularビルドまたはサーバーバンドル内にではないで出荷されますが、基礎となるdatabase。すべての翻訳は起動時に読み込まれ、JSON構造に変換されてから、フロントエンドに配信され、ngx-translateが残りを処理します。データベースから翻訳を正常に読み込み、フロントエンドからアクセスできるようにするための簡単なイベントの順序を次に示します。

  1. データベースでの安全な翻訳
  2. バックエンドの起動時に翻訳をロードする(またはリロードメカニズムを実装する(おそらくRESTを使用))
  3. 変換をキーと値のペアのJSONオブジェクトにマッピングする
  4. REST apiを介してJSONオブジェクトにアクセスできるようにします
  5. フロントエンドはこのREST apiを介してJSONオブジェクトをロードします
  6. angular with ngx-translate でJSONオブジェクトを使用する

利点

これがどのように見えるかについては後で詳しく説明しますが、このdatabase-rest-approachがもたらす利点について簡単に説明します。

  • 1つの場所(1つのテーブル)に保存されているすべての翻訳
  • 言語の欠落した翻訳を回避することができます(NULLチェック)
  • 二重キーの割り当てを回避できます(主キー)
  • 翻訳中の更新実行中が可能です
  • 翻訳プロセスはプロジェクトの外部で行うことができます(プロジェクト構造のファイルを更新する必要はありません)

これを実現する方法を見てみましょう。

データベース

翻訳は通常、翻訳ファイルに基づく単純なキーと値のペアで構成されます。そのため、代わりに、key列とtranslation列を含む単一のテーブルに翻訳を保存します。 _KEY | EN | FR | DE_のような値を持つ_button.close | close | près | schließen_のような例。キーは通常のファイルと同じキーを表しますが、言語ごとに区切られたファイルではなく、翻訳がそれぞれ1つの列に保存されます。

jSONオブジェクトへのバックエンドマッピング

テーブル全体を一度にロードして、フロントエンド配信のすべての言語を一度に準備するのが好きです。これは通常、バックエンドの起動時に1回行うことができ、多くのデータベース呼び出しを回避するために結果をメモリに保持できます。テーブルは、言語列ごとにキーと値のペアのJSONオブジェクトに分離する必要があります。結果のすべての言語オブジェクトには、キーとしてデータベースキーが含まれ、値として翻訳が含まれます。

_var EN = {
    ...
    "button.close": "close",
    ...
}
var FR = {
    ...
    "button.close": "près",
    ...
}
var DE = {
    ...
    "button.close": "schließen",
    ...
}
_

これは、配列からオブジェクトへのマッピングにすぎません。これは、サーバー言語にもよりますが、通常は非常に単純です(必要に応じて、node.jsのコードを共有できます)。結果はJSON言語オブジェクトのリストで、それぞれにキーと値のペアとして変換され、後でアクセスできます。

HTTPレストコール

翻訳は、通常の翻訳ファイル(キーと値のペア)とほぼ同じ形式になり、ファイルではなくメモリに保持されます。特定の言語の単純なHTTP api呼び出しを使用すると、このリストにアクセスし、この言語の翻訳オブジェクトを取得して、フロントエンドに直接送信できます。ここに_node.js_エクスプレスの例があります。

_translationRouter.route('/:lang').get(function (request, response) {
    // load translation key-value-pair object for requested language
    response.send(translationService.getTranslations(request.params.lang));
});
_

ngx-translate

ngx-translate の動作は非常に簡単です。翻訳はangularアプリにロードされます。翻訳キーはアプリで指定され、動的に提供された言語の翻訳値に置き換えられます。他の人が述べたように、翻訳、たとえばプレーンな古い翻訳ファイルやHTTPローダーなどの自己実装ローダー。REST呼び出し(上記参照)を介して翻訳をロードする単純なHTTPローダーは次のとおりです。

_import { TranslateLoader } from '@ngx-translate/core';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
import '../rxjs-operators';

export class TranslationLoader implements TranslateLoader {
    constructor(private http: HttpClient) { }

    getTranslation(lang: string): Observable<any> {
        return this.http.get("/api/translation/" + lang);
    }
}
_

唯一のトリックは、このローダーをメインローダーとして指定することです。これは、app.moduleで実行できます。上記のHTTPローダーを使用する例を次に示します(AOTでも機能します)。

_import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
export function HttpLoaderFactory(http: HttpClient) {
    return new TranslationLoader(http);
}
...
@NgModule({
    imports: [..., 
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: (HttpLoaderFactory),
                deps: [HttpClient]
            }
        }), ...]
})
_

ngx-translate は、ファイルを要求する代わりに、指定されたTranslationLoaderを使用してキーと値のペアを取得します。これは、残りの呼び出しを通じて提供されるものです。かんたん。この場合、ロードする言語を指定できます。さらに、値が見つからない場合のフォールバック言語を指定できます。デフォルト言語の翻訳とブラウザ言語の翻訳をロードする例を次に示します。

_// fallback language
this.translate.setDefaultLang('en');
// browser language
this.translate.use(this.translate.getBrowserLang());
_

Ngx-translateのドキュメントは非常に優れています。たとえば、サービス、ディレクティブ、パイプなど、さまざまな使用方法があり、さらに翻訳をパラメータ化することもできます。


追加情報

翻訳の再読み込み

メリットリストに記載されているように、実行時に翻訳を再読み込みすることもできます。これは、アプリを配信用にバンドルする場合、おそらくより複雑になります。起動時とまったく同じ変換ロードプロシージャを実行する管理者にHTTP REST呼び出しを提供するだけです。このようにして、翻訳を再読み込み、再マッピング、メモリに保存できます。新しいページリクエストでは、再読み込みされた翻訳オブジェクトが自動的に使用されます。

ライブ言語変更

Ngx-translateを使用するいくつかの方法では、(たとえば、ディレクティブを介して)インスタント翻訳の切り替えが可能です。このように、angular(単純なthis.translate.use(lang)呼び出しを介して)で別の言語をロードすると、ページや可視コンポーネントを再ロードすることなく、表示された翻訳が即座に切り替わります。残念ながら、すべての使用方法で機能するわけではありません。

ngx-translateの制限

Ngx-translateは本当に使いやすいですが、制限があります。その1つは、たとえば、ngx-translateディレクティブを angular material ディレクティブのほとんどと組み合わせて使用​​することです。これは、angularマテリアルディレクティブ(ボタンなど)がサブツリー構造を作成し、ngx-translateは最初の子のキーのみを変換します(少なくとも私はそうだと思います)使用するのはかっこいいですが、時には少しトリッキーです。



それだと思います。私は現在このアプローチを使用しており、その結果に非常に満足しています。それを始めるのは少しの仕事ですが、すべてがうまくいったら、それはかなり役に立ちます。

25

Angularに組み込まれている国際化よりもAPIが優れている ngx-translate (以前はng2-translateと呼ばれていました)ライブラリを使用することをお勧めします...静的jsonファイル(バックエンドで生成可能)からの翻訳または例toml-loaderを追加し、以下の例のように翻訳をファイルassets/i18n/en.tomlに保存します。

[homepage]
title = "Homepage title"
contact = "Contact"

[auth]
login = "Log in"
logout = "Log out"

[settings]
settings = "Settings"
body = "<b>HTML</b> is fine here"

次のように使用します。

<h2>{{'settings.settings' | translate}}</h2>
<p [innerHTML]="'settings.body' | translate"></p>
{{'auth.logout' | translate}}

すべてを設定するには、基本的に数行のコードが必要です。

import * as translation_en from 'toml-loader!../assets/i18n/en.toml';

@Injectable()
export class AppService {
    constructor(private translateService: TranslateService) {
        translateService.setDefaultLang('en');
        translateService.setTranslation('en', translation_en);
        translateService.use('en');
    }
}

それが役に立てば幸い!

3
Daniel Kucal

angular-l10n ライブラリを使用することをお勧めします。これは、angularローカリゼーション用のi18nの代替オープンソースです。JSON形式を使用し、サービスからのロードもサポートします。ドキュメントへのリンクもあります。 angular-l10n configuration Web APIからの読み込みに関する情報を見つけるには、ページで「翻訳データの読み込み」を検索してください。

2
AlesD

ngx-translateの作成者はAngular i18nコアチームに所属しており、Angular 5.xの一部として機能していることに注意してください。例えば、i18​​nをより良くすることに関するものです。たとえば、翻訳サービス、AOTでの実行時翻訳の切り替えなど。

ここを参照してください: https://github.com/angular/angular/issues/11405#issuecomment-343933617

だから私はAngularすぐに使えるi18nに固執することをお勧めします。

私の会社のウェブサイトでは、翻訳にText Unitedを使用していますが、これはかなりうまくいきます。唯一の問題は、デフォルトでHTMLタグが翻訳ツールに含まれることです。私たちのソリューションは:

  • xTBの使用
  • Text Unitedでは、カスタムXMLパーサーを使用しています。 ph要素を除外します。

テキストユナイテッドは、任意の言語であなたのために仕事をしてくれる翻訳者を雇うためのオプションを支払っています。もちろん、あなたもそれを自分で行うことができます。ソース言語をアップロードするたびに、すでに翻訳済みのアイテムと一致します。

1
Boland

ngx-translate Angular 2+の国際化対応の標準ライブラリです。

ライブラリをインポートして、翻訳を含むjsonファイルのセットを作成し、アセットフォルダ内に配置できます。

その後、HTMLで参照できます。例えば言いなさい。

en.jsonは、

"guest.first-name": "first Name",

1つ目はキー、2つ目は表示する値です。そして、あなたはhtmlで参照することができます、

<input  [label]="'guest.first-name' | translate" type="text" name="form_name" [(ngModel)]="firstName" required="required" ></input>
1
Sajeetharan

Transloco も検討してください。 JSONストレージ形式を使用し、JSONファイルをロードできます 任意のソースから ので、データベースにロードしてサービスに返す前に再フォーマットできます。

これがローカリゼーション(l10n)ソリューションであり、完全な国際化(i18n)ソリューションではないことを私は認めるべきではありませんが、とにかくあなたが探しているすべてのものかもしれません。

0
cjbarth

私のプロジェクトでは、文字列リテラル(国際化が必要)がx.y.z="Hello World"のような形式で別のファイルに保存されています。この文字列をJSONオブジェクトに変換するスクリプトを開発しました。

x { y { z: { default: "Hello World" } } }

そして、「ng2-translate」ライブラリを使用して、このJSONファイルをangular 4プロジェクトの国際化に使用しました。

0
Ashish Patel