Heim  >  Artikel  >  Web-Frontend  >  So implementieren Sie die Internationalisierung mit Angular (ausführliches Tutorial)

So implementieren Sie die Internationalisierung mit Angular (ausführliches Tutorial)

亚连
亚连Original
2018-06-13 10:06:122910Durchsuche

Dieser Artikel stellt hauptsächlich die Methode der Internationalisierung von Angular-Projekten vor. Jetzt teile ich ihn mit Ihnen und gebe Ihnen eine Referenz.

Wie es auf der offiziellen Website von Angular heißt, ist die Internationalisierung von Projekten eine herausfordernde Aufgabe, die vielschichtige Anstrengungen, dauerhaftes Engagement und Entschlossenheit erfordert.
In diesem Artikel wird der Internationalisierungsplan des Angular-Projekts vorgestellt, der die Internationalisierung statischer Dateien (HTML) und das Verfassen von Texten für TS-Dateien umfasst.

Hintergrund

  1. Angular: 5.0

  2. Angular Cli: 1.6.1(1.5.x Auch verfügbar)

  3. NG-ZORRO: 0,6,8

Angular i18n

i18n-Vorlage Der Übersetzungsprozess besteht aus vier Phasen:

  1. Markieren Sie die statischen Textinformationen, die übersetzt werden müssen, in der Komponentenvorlage (d. h. fügen Sie das i18n-Tag hinzu).

  2. Das i18n-Tool von Angular extrahiert die getaggten Informationen in eine branchenübliche Übersetzungsquelldatei (z. B. eine XLF-Datei mit ng xi18n).

  3. Der Übersetzer bearbeitet die Datei, übersetzt die extrahierten Textinformationen in die Zielsprache und sendet die Datei an Sie zurück (erfordert Übersetzerzugriff, dieser Artikel verwendet die XLF-Datei zur Dateiausgabe im JSON-Format und konvertieren Sie schließlich die JSON-Datei zurück in eine Datei im XLF-Format.

  4. Der Angular-Compiler importiert die übersetzte Datei, ersetzt die Originalinformationen durch den übersetzten Text und generiert eine neue Zielsprachenversion der Anwendung.

Sie können für jede unterstützte Sprache separate Projektversionen erstellen und bereitstellen, indem Sie einfach die übersetzten XLF-Dateien ersetzen.

Wie verwende ich es in Vorlagendateien?

i18n bietet mehrere Verwendungsmöglichkeiten und bietet auch Übersetzungsmethoden für Singular- und Pluralzahlen (ich habe es persönlich nicht verwendet, daher fühlt es sich unpraktisch an). Als nächstes wird eine separate HTML-Datei verwendet, um verschiedene Verwendungsmethoden vorzustellen.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Angular i18n</title>
</head>
<body>
  <h1 i18n="Site Header|An introduction header for i18n Project@@stTitle">Angular 国际化项目</h1>
  <p>
   <span i18n="@@agDescription">国际化是一项很具有挑战性,需要多方面的努力、持久的奉献和决心的任务。</span>
   <span class="delete" i18n-title="@@agDelete" title="删除"></span>
  </p>
  <p><ng-container i18n=@@agLetGo>让我们现在开始吧!</ng-container>朋友!</p>
</body>
</html>

Der obige Code zeigt mehrere Möglichkeiten zur Verwendung von i18n:

1. Verwenden Sie i18n-Attribut-Tags (erläuternde Kopien können hinzugefügt werden, das Format ist: Titel|Beschreibung@@ID, Titel und Beschreibung (kann Übersetzern helfen, die Bedeutung des Copywritings besser zu verstehen, hängt von der Situation Ihres eigenen Projekts ab)

kann das i18n-Tag direkt auf dem statischen Tag markieren, z. B. dem von

<span i18n="@@agDescription"></span>

) Feldformat ist

<trans-unit id="agDescription" datatype="html">
 <source>国际化是一项很具有挑战性,需要多方面的努力、持久的奉献和决心的任务。</source>
 <context-group purpose="location">
  <context context-type="sourcefile">xxx.ts</context>
  <context context-type="linenumber">linenum</context>
 </context-group>
</trans-unit>

2. i18n-Attribut zum Titel hinzufügen

Für das HTML-Tag-Attribut können Sie auch i18n hinzufügen, z. B. das generierte xlf (xml)-Format von

<span class="delete" i18n-title="@@agDelete" title="删除"></span>

ist das Gleiche wie oben

3. Übersetzen Sie Text, ohne Elemente zu erstellen

Manchmal haben wir mehrere Satzfragmente in einem Satz, wenn wir Elemente wie span und hinzufügen Wenn Sie jedes Mal ein Etikett verwenden, kann dies das Seitenlayout erheblich beeinträchtigen. Zu diesem Zeitpunkt können wir ng-container verwenden, um die zu übersetzende Kopie zu verpacken.

<p>
  <ng-container i18n=@@agLetGo>让我们现在开始吧!</ng-container>朋友!
</p>

wird auf der Seite als

<p>
  <!---->
  LET&#39;S GO朋友!
</p>

* angezeigt. ng-container wird zu einem Kommentarblock, der sich nicht auf das Seitenlayout auswirkt (insbesondere, wenn ein Stil angewendet wird)

Danach Beim Markieren müssen wir nur ng xi18n ausführen, um automatisch eine XLF-Datei zu erstellen, normalerweise message.xlf. Wenn Sie sie anpassen müssen, können Sie sie auf der offiziellen Website von Angular CLI anzeigen.

XLF- und JSON-Konvertierung

XLF-zu-JSON-Methode

Ich persönlich verwende für den Betrieb die xml2js-Bibliothek. Der einfache Code lautet wie folgt:

const fs = require(&#39;fs&#39;);
xml2js = require(&#39;xml2js&#39;);
var parser = new xml2js.Parser();
fs.readFile(fileName, &#39;utf8&#39;, (err, data) => {
 parser.parseString(data, function (err, result) {
  // 读取新文件全部需要翻译的数据,并对比已翻译的进行取舍,具体转换成的格式结构可自行查看
  result[&#39;xliff&#39;][&#39;file&#39;][0][&#39;body&#39;][0][&#39;trans-unit&#39;].forEach((item) => {
   var itemFormat = {
    "key" : item[&#39;$&#39;][&#39;id&#39;],
    "value": item[&#39;source&#39;][0]
   };
   // 执行相关操作,key-value形式是为了统一翻译文件结构,可按需定义
  })
 });
});

json to xlf method

function backToXLF(translatedParams) {
 // 文件格式可自行参考angular.cn官网的例子
 var xlfFormat = {
  "xliff": {
   "$"  : {
    "version": "1.2",
    "xmlns" : "urn:oasis:names:tc:xliff:document:1.2"
   },
   "file": [
    {
     "$"  : {
      "source-language": "en",
      "datatype"    : "plaintext",
      "original"    : "ng2.template"
     },
     "body": [
      {
       "trans-unit": []
      }
     ]
    }
   ]
  }
 };
 if (translatedParams instanceof Array) {
  // 获取原始名称
  translatedParams.forEach((data) => {
   var tmp = {
    "$"   : {
     "id"   : data.key,
     "datatype": "html"
    },
    "source": [i18nItemsOrigin[data.key]], // 这里的i18nItemsOrigin是json格式,属性名为key值,表示原始文案
    "target": [data.value]
   };
   // 数组,json项
   xlfFormat[&#39;xliff&#39;][&#39;file&#39;][0][&#39;body&#39;][0][&#39;trans-unit&#39;].push(tmp);
  });
 }
 var builder = new xml2js.Builder();
 var xml = builder.buildObject(xlfFormat);
 return xml;
}

Auf diese Weise sind die Extraktion der Kopieinformationen und die Konvertierung der übersetzten Datei abgeschlossen. Als nächstes müssen wir die übersetzte Kopie auf das Projekt anwenden.

Übersetzungsdateien bereitstellen

Erstellen Sie einen Gebietsschemaordner im src-Verzeichnis und speichern Sie die übersetzte Datei demo.en-US.xlf im geänderten Verzeichnis

Erstellen Sie eine neue i18n-providers.ts

import {
 LOCALE_ID,
 MissingTranslationStrategy,
 StaticProvider,
 TRANSLATIONS,
 TRANSLATIONS_FORMAT
} from &#39;@angular/core&#39;;
import { CompilerConfig } from &#39;@angular/compiler&#39;;
import { Observable } from &#39;rxjs/Observable&#39;;
import { LOCALE_LANGUAGE } from &#39;./app.config&#39;; // 自行定义配置位置

export function getTranslationProviders(): Promise<StaticProvider[]> {

 // get the locale string from the document
 const locale = LOCALE_LANGUAGE.toString();

 // return no providers
 const noProviders: StaticProvider[] = [];

 // no locale or zh-CN: no translation providers
 if (!locale || locale === &#39;zh-CN&#39;) {
  return Promise.resolve(noProviders);
 }

 // Ex: &#39;locale/demo.zh-MO.xlf`
 const translationFile = `./locale/demo.${locale}.xlf`;

 return getTranslationsWithSystemJs(translationFile)
  .then((translations: string) => [
   { provide: TRANSLATIONS, useValue: translations },
   { provide: TRANSLATIONS_FORMAT, useValue: &#39;xlf&#39; },
   { provide: LOCALE_ID, useValue: locale },
   {
    provide: CompilerConfig,
    useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error })
   }
  ]).catch(() => noProviders); // ignore if file not found
}

declare var System: any;
// 获取locale文件
function getTranslationsWithSystemJs(file: string) {
 let text = &#39;&#39;;
 const fileRequest = new XMLHttpRequest();
 fileRequest.open(&#39;GET&#39;, file, false);
 fileRequest.onerror = function (err) {
  console.log(err);
 };
 fileRequest.onreadystatechange = function () {
  if (fileRequest.readyState === 4) {
   if (fileRequest.status === 200 || fileRequest.status === 0) {
    text = fileRequest.responseText;
   }
  }
 };
 fileRequest.send();
 const observable = Observable.of(text);
 const prom = observable.toPromise();
 return prom;
}

main.ts-Datei im App-Ordner und ändern Sie sie in

import { enableProdMode } from &#39;@angular/core&#39;;
import { platformBrowserDynamic } from &#39;@angular/platform-browser-dynamic&#39;;

import { AppModule } from &#39;./app/app.module&#39;;
import { environment } from &#39;./environments/environment&#39;;
import { getTranslationProviders } from &#39;./app/i18n-providers&#39;;

if (environment.production) {
 enableProdMode();
}

getTranslationProviders().then(providers => {
 const options = { providers };
 platformBrowserDynamic().bootstrapModule(AppModule, options)
  .catch(err => console.log(err));
});

Vergessen Sie nicht, das Gebietsschemaverzeichnis zu .angular-cli hinzuzufügen .json, um das Paket zu trennen.

Auf diese Weise ist unsere Übersetzung statischer Kopien im Grunde abgeschlossen, aber wie sollen wir einige dynamische Kopien übersetzen, z. B. Kopien in TS-Dateien oder Frame-Attribute von Drittanbietern? Im Folgenden wird die Lösung für die dynamische Kopierübersetzung für TS-Dateien und das NG-ZORRO-Framework vorgestellt.

TS-Datei-Copywriting und NG-ZORRO-Framework-Copywriting-Übersetzung

Spezifische Ideen

Rufen Sie die Service-Methode über Pipe auf und passen Sie JSON entsprechend dem entsprechenden Unique an ID-Wert Die Übersetzungsergebnisse im Objekt werden dann zum Rendern an das Front-End zurückgegeben, wobei auf den internationalen Implementierungsplan des NG-ZORRO-Frameworks verwiesen wird.

Zuerst definieren wir das Format des JSON-Übersetzungsobjekts, bei dem es sich um eine dreischichtige Struktur handelt, die mit %% umschlossen werden muss. Der Grund dafür ist, dass es mit der Projektstruktur zusammenhängt erleichtert später die Vereinheitlichung des Formats mit i18n.

{
  "app": {
    "base": {
      "hello": "文件文案",
      "userCount": "一共%num%人"
    }
  }
}

Das Format wurde festgelegt, wir definieren weiterhin die Service-Verarbeitungsmethode

Die Internationalisierungslösung von NG-ZORRO wird hier wiederverwendet, was unsere Entwicklung vereinfachen kann. Wenn Sie interessiert sind kann auf seinen Quellcode verweisen.

*** TranslateService ***
import { Injectable } from &#39;@angular/core&#39;;
// 引入语言配置和国际化文件文案对象
import { LOCALE_LANGUAGE } from &#39;../app.config&#39;;
import { enUS } from &#39;../locales/demo.en-US&#39;;
import { zhCN } from &#39;../locales/stream.zh-CN&#39;;

@Injectable()
export class TranslateService {

 private _locale = LOCALE_LANGUAGE.toString() === &#39;zh-CN&#39; ? zhCN : enUS;

 constructor() {
 }
 // path为app.base.hello格式的字符串,这里按json层级取匹配改变量
 translate(path: string, data?: any): string {
  let content = this._getObjectPath(this._locale, path) as string;
  if (typeof content === &#39;string&#39;) {
   if (data) {
    Object.keys(data).forEach((key) => content = content.replace(new RegExp(`%${key}%`, &#39;g&#39;), data[key]));
   }
   return content;
  }
  return path;
 }

 private _getObjectPath(obj: object, path: string): string | object {
  let res = obj;
  const paths = path.split(&#39;.&#39;);
  const depth = paths.length;
  let index = 0;
  while (res && index < depth) {
   res = res[paths[index++]];
  }
  return index === depth ? res : null;
 }
}

Auf diese Weise müssen Sie nur die Übersetzungsmethode von Service in Pipe aufrufen

*** NzTranslateLocalePipe ***
import { Pipe, PipeTransform } from &#39;@angular/core&#39;;
import { TranslateService } from &#39;../services/translate.service&#39;;

@Pipe({
 name: &#39;nzTranslateLocale&#39;
})
export class NzTranslateLocalePipe implements PipeTransform {
 constructor(private _locale: TranslateService) {
 }

 transform(path: string, keyValue?: object): string {
  return this._locale.translate(path, keyValue);
 }
}

Okay, jetzt, da unsere Verarbeitungslogik vollständig abgeschlossen ist, zeigen wir Ihnen, wie Sie

*** NG-ZORRO 控件 ***
<nz-input [nzPlaceHolder]="&#39;app.base.hello&#39;|nzTranslateLocale"></nz-input> // 无动态参数
<nz-popconfirm [nzTitle]="&#39;app.base.userCount&#39;|nzTranslateLocale: {num:users.length}" ...>
... // 有动态参数
</nz-popconfirm>

*** ts文件 ***
export class AppComponent implements OnInit {
 demoTitle=&#39;&#39;;
 users = [&#39;Jack&#39;, &#39;Johnson&#39;, &#39;Lucy&#39;];
 constructor(privete translateService: TranslateService) {
 }
 ngOnInit() {
  this.demoTitle = this.translateService.translate(&#39;app.base.hello&#39;);
 }
}
verwenden

Der obige Prozess kann grundsätzlich den Internationalisierungsanforderungen der meisten Winkelprojekte gerecht werden. Wenn eine komplexere Internationalisierung erforderlich ist, ist eine Diskussion willkommen.

Zusammenfassung

Die Internationalisierung von Angular auf 5.0 war relativ einfach. Wir müssen nur i18n an der entsprechenden Stelle markieren, um die zu übersetzende Kopie einfach und schnell zu extrahieren Was ist das Besondere? Die Verarbeitung übersetzter Dateien ist von Person zu Person unterschiedlich, und mehrere Methoden können uns bei der Konvertierung helfen (wie dieser Artikel über nodejs).

Was komplizierter ist, ist der Text, der nicht durch Eingabe von i18n-Tags übersetzt werden kann. Die Internationalisierungslösung von NG-ZORRO gleicht die Mängel in diesem Aspekt aus und kann in Kombination die Internationalisierung des Projekts problemlos abschließen. Wenn es keine engagierte Teamunterstützung für die Internationalisierung gibt, wird die Übersetzung sehr schwierig sein, und es gibt viele Dinge zu berücksichtigen, wie z. B. traditionelles Chinesisch, traditionelles Macau-Chinesisch, traditionelles Taiwan-Chinesisch usw., und auch die Grammatik ist anders.

Referenzverzeichnis

Online-Beispiel für die Internationalisierung von Angular (i18n)
NG-ZORRO Locale Internationalization

Das Obige habe ich zusammengestellt alle Ja, ich hoffe, es wird in Zukunft für alle hilfreich sein.

Verwandte Artikel:

Wie implementiert man die Formularvalidierung mit JQuery, was ist konkret zu tun?

So legen Sie mehrere Klassen mit Vue fest

So erhalten Sie den Wert des Mehrfachauswahlfeldwerts in einem Beitrag in SpringMVC (Code Beispiel)

Beispiel für Kontrollkästchenauswahl und Wertübergabe in jQuery+SpringMVC_jquery

Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Internationalisierung mit Angular (ausführliches Tutorial). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn