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.
Angular: 5.0
Angular Cli: 1.6.1(1.5.x Auch verfügbar)
NG-ZORRO: 0,6,8
i18n-Vorlage Der Übersetzungsprozess besteht aus vier Phasen:
Markieren Sie die statischen Textinformationen, die übersetzt werden müssen, in der Komponentenvorlage (d. h. fügen Sie das i18n-Tag hinzu).
Das i18n-Tool von Angular extrahiert die getaggten Informationen in eine branchenübliche Übersetzungsquelldatei (z. B. eine XLF-Datei mit ng xi18n).
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.
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 < generierten xlf(xml). 🎜>
<span i18n="@@agDescription"></span>
<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>
<span class="delete" i18n-title="@@agDelete" title="删除"></span>
<p> <ng-container i18n=@@agLetGo>让我们现在开始吧!</ng-container>朋友! </p>
<p> <!----> LET'S GO朋友! </p>
XLF- und JSON-Konvertierung
XLF-zu-JSON-MethodeIch persönlich verwende für den Betrieb die xml2js-Bibliothek. Der einfache Code lautet wie folgt:const fs = require('fs'); xml2js = require('xml2js'); var parser = new xml2js.Parser(); fs.readFile(fileName, 'utf8', (err, data) => { parser.parseString(data, function (err, result) { // 读取新文件全部需要翻译的数据,并对比已翻译的进行取舍,具体转换成的格式结构可自行查看 result['xliff']['file'][0]['body'][0]['trans-unit'].forEach((item) => { var itemFormat = { "key" : item['$']['id'], "value": item['source'][0] }; // 执行相关操作,key-value形式是为了统一翻译文件结构,可按需定义 }) }); });
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['xliff']['file'][0]['body'][0]['trans-unit'].push(tmp); }); } var builder = new xml2js.Builder(); var xml = builder.buildObject(xlfFormat); return xml; }
import { LOCALE_ID, MissingTranslationStrategy, StaticProvider, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core'; import { CompilerConfig } from '@angular/compiler'; import { Observable } from 'rxjs/Observable'; import { LOCALE_LANGUAGE } from './app.config'; // 自行定义配置位置 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 === 'zh-CN') { return Promise.resolve(noProviders); } // Ex: '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: 'xlf' }, { 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 = ''; const fileRequest = new XMLHttpRequest(); fileRequest.open('GET', 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; }
import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; import { getTranslationProviders } from './app/i18n-providers'; if (environment.production) { enableProdMode(); } getTranslationProviders().then(providers => { const options = { providers }; platformBrowserDynamic().bootstrapModule(AppModule, options) .catch(err => console.log(err)); });
{ "app": { "base": { "hello": "文件文案", "userCount": "一共%num%人" } } }
*** TranslateService *** import { Injectable } from '@angular/core'; // 引入语言配置和国际化文件文案对象 import { LOCALE_LANGUAGE } from '../app.config'; import { enUS } from '../locales/demo.en-US'; import { zhCN } from '../locales/stream.zh-CN'; @Injectable() export class TranslateService { private _locale = LOCALE_LANGUAGE.toString() === 'zh-CN' ? 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 === 'string') { if (data) { Object.keys(data).forEach((key) => content = content.replace(new RegExp(`%${key}%`, 'g'), data[key])); } return content; } return path; } private _getObjectPath(obj: object, path: string): string | object { let res = obj; const paths = path.split('.'); const depth = paths.length; let index = 0; while (res && index < depth) { res = res[paths[index++]]; } return index === depth ? res : null; } }
*** NzTranslateLocalePipe *** import { Pipe, PipeTransform } from '@angular/core'; import { TranslateService } from '../services/translate.service'; @Pipe({ name: 'nzTranslateLocale' }) export class NzTranslateLocalePipe implements PipeTransform { constructor(private _locale: TranslateService) { } transform(path: string, keyValue?: object): string { return this._locale.translate(path, keyValue); } }
*** NG-ZORRO 控件 *** <nz-input [nzPlaceHolder]="'app.base.hello'|nzTranslateLocale"></nz-input> // 无动态参数 <nz-popconfirm [nzTitle]="'app.base.userCount'|nzTranslateLocale: {num:users.length}" ...> ... // 有动态参数 </nz-popconfirm> *** ts文件 *** export class AppComponent implements OnInit { demoTitle=''; users = ['Jack', 'Johnson', 'Lucy']; constructor(privete translateService: TranslateService) { } ngOnInit() { this.demoTitle = this.translateService.translate('app.base.hello'); } }
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!