成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Angular 項(xiàng)目 國(guó)際化

cncoder / 1373人閱讀

摘要:正如官網(wǎng)所說(shuō),項(xiàng)目國(guó)際化是一件具有挑戰(zhàn)性,需要多方面的努力持久的奉獻(xiàn)和決心的任務(wù)。本文將介紹項(xiàng)目的國(guó)際化方案,涉及靜態(tài)文件和文件文案的國(guó)際化。參考目錄的國(guó)際化在線(xiàn)例子國(guó)際化

正如angular官網(wǎng)所說(shuō),項(xiàng)目國(guó)際化是一件具有挑戰(zhàn)性,需要多方面的努力、持久的奉獻(xiàn)和決心的任務(wù)。
本文將介紹angular項(xiàng)目的國(guó)際化方案,涉及靜態(tài)文件(html)和ts文件文案的國(guó)際化。

背景

Angular: 5.0

Angular Cli: 1.6.1(1.5.x也可以)

NG-ZORRO: 0.6.8

Angular i18n
i18n模板翻譯流程有四個(gè)階段:

在組件模板中標(biāo)記需要翻譯的靜態(tài)文本信息(即打上i18n標(biāo)簽)。

Angular的i18n工具將標(biāo)記的信息提取到一個(gè)行業(yè)標(biāo)準(zhǔn)的翻譯源文件(如.xlf文件,使用ng xi18n)。

翻譯人員編輯該文件,翻譯提取出來(lái)的文本信息到目標(biāo)語(yǔ)言,并將該文件還給你(需要翻譯人員接入,本文采用將xlf文件轉(zhuǎn)為json格式文件輸出,最終將json文件轉(zhuǎn)換回xlf格式文件)。

Angular編譯器導(dǎo)入完成翻譯的文件,使用翻譯的文本替換原始信息,并生成新的目標(biāo)語(yǔ)言版本的應(yīng)用程序。

你可以為每種支持的語(yǔ)言構(gòu)建和部署多帶帶的項(xiàng)目版本,僅需替換翻譯后的xlf文件即可。
如何在模板文件中使用?

i18n提供了幾種使用方式,還專(zhuān)門(mén)為單復(fù)數(shù)提供了翻譯方式(個(gè)人沒(méi)有使用,感覺(jué)不太方便)。接下來(lái)以一個(gè)多帶帶的html文件來(lái)介紹幾種使用方法。





Angular i18n


    

Angular 國(guó)際化項(xiàng)目

國(guó)際化是一項(xiàng)很具有挑戰(zhàn)性,需要多方面的努力、持久的奉獻(xiàn)和決心的任務(wù)。

讓我們現(xiàn)在開(kāi)始吧!朋友!

上述代碼展示了幾種i18n的使用方式:

1、使用i18n屬性標(biāo)記(可添加上說(shuō)明性文案,格式如:title|description@@id,title和description可幫助翻譯人員更好地理解文案含義,是否添加取決于自身項(xiàng)目情況)
可以在靜態(tài)標(biāo)簽上直接打上i18n的tag,如

生成的xlf(xml)字段格式為

  國(guó)際化是一項(xiàng)很具有挑戰(zhàn)性,需要多方面的努力、持久的奉獻(xiàn)和決心的任務(wù)。
  
    xxx.ts
    linenum
  

2、為title添加i18n屬性
對(duì)于html標(biāo)簽屬性,同樣可以添加i18n,如

生成的xlf(xml)格式同上
3、翻譯文本,而不必創(chuàng)建元素
我們有時(shí)候會(huì)出現(xiàn)一句話(huà)多個(gè)斷句情況,如果每次都添加span、label這些元素包裹的話(huà),可能?chē)?yán)重影響頁(yè)面布局,這時(shí)候我們可以使用ng-container來(lái)包裹需要翻譯的文案。

讓我們現(xiàn)在開(kāi)始吧!朋友!

在頁(yè)面顯示為

LET"S GO朋友!

* ng-container變?yōu)榱俗⑨寜K,這樣做不會(huì)影響頁(yè)面布局(尤其是應(yīng)用了style樣式的情況)

打上標(biāo)簽后,我們只要執(zhí)行ng xi18n即可自動(dòng)創(chuàng)建出xlf文件,通常為message.xlf,如需自定義,可自行前往 Angular CLI 官網(wǎng)查看。

XLF與JSON轉(zhuǎn)換
xlf轉(zhuǎn)json方法
我個(gè)人是采用xml2js庫(kù)進(jìn)行操作,簡(jiǎn)單代碼如下:
const fs = require("fs");
xml2js = require("xml2js");
var parser = new xml2js.Parser();
fs.readFile(fileName, "utf8", (err, data) => {
  parser.parseString(data, function (err, result) {
    // 讀取新文件全部需要翻譯的數(shù)據(jù),并對(duì)比已翻譯的進(jìn)行取舍,具體轉(zhuǎn)換成的格式結(jié)構(gòu)可自行查看
    result["xliff"]["file"][0]["body"][0]["trans-unit"].forEach((item) => {
      var itemFormat = {
        "key"  : item["$"]["id"],
        "value": item["source"][0]
      };
      // 執(zhí)行相關(guān)操作,key-value形式是為了統(tǒng)一翻譯文件結(jié)構(gòu),可按需定義
    })
  });
});
json轉(zhuǎn)xlf方法
function backToXLF(translatedParams) {
  // 文件格式可自行參考angular.cn官網(wǎng)的例子
  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) {
    // 獲取原始名稱(chēng)
    translatedParams.forEach((data) => {
      var tmp = {
        "$"     : {
          "id"      : data.key,
          "datatype": "html"
        },
        "source": [i18nItemsOrigin[data.key]], // 這里的i18nItemsOrigin是json格式,屬性名為key值,表示原始文案
        "target": [data.value]
      };
      // 數(shù)組,json項(xiàng)
      xlfFormat["xliff"]["file"][0]["body"][0]["trans-unit"].push(tmp);
    });
  }
  var builder = new xml2js.Builder();
  var xml = builder.buildObject(xlfFormat);
  return xml;
}

這樣提取文案信息和轉(zhuǎn)換翻譯后的文件就完成了,接下來(lái)我們需要把翻譯好的文案應(yīng)用到項(xiàng)目中去。
部署翻譯文件

JIT模式
src目錄下新建locale文件夾,將翻譯轉(zhuǎn)換后的demo.en-US.xlf文件存在改目錄下
app文件夾下新建i18n-providers.ts

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 {

  // 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;
}

main.ts文件修改為

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));
});

別忘了將locale目錄添加到.angular-cli.json里,來(lái)多帶帶打包。

AOT模式(推薦)

對(duì)于AOT模式打包的持續(xù)來(lái)說(shuō),不需要上述復(fù)雜的配置,只需要在原有build基礎(chǔ)上,加上相應(yīng)的i18n文件即可,如:

ng build --prod --build-optimizer -bh / --i18n-format=xlf --locale=en --i18n-file=./src/locale/demo.en-US.xlf

這樣打出的包會(huì)自動(dòng)將翻譯文件應(yīng)用到項(xiàng)目中。

這樣我們對(duì)靜態(tài)文案的翻譯工作基本已經(jīng)完成了,但是有些動(dòng)態(tài)文案如ts文件里的文案或者第三方框架屬性該如何翻譯呢?下面會(huì)介紹針對(duì) ts 文件和 NG-ZORRO 框架實(shí)現(xiàn)動(dòng)態(tài)文案翻譯的方案。

ts文件文案和NG-ZORRO框架文案翻譯
具體思路
通過(guò)Pipe調(diào)用Service方法,根據(jù)對(duì)應(yīng)的唯一id值匹配json對(duì)象里的翻譯結(jié)果,進(jìn)而返回渲染到前端,參考于NG-ZORRO框架的國(guó)際化實(shí)現(xiàn)方案。

首先我們定義一下json翻譯對(duì)象的格式,全部為三層結(jié)構(gòu),動(dòng)態(tài)變量需要按%%包裹,這樣做的原因是和項(xiàng)目結(jié)構(gòu)相關(guān)聯(lián),也便于后期和i18n方式格式統(tǒng)一。

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

格式已定,我們繼續(xù)定義Service處理方式
這里復(fù)用 NG-ZORRO的國(guó)際化方案 ,可以簡(jiǎn)化我們的開(kāi)發(fā),有興趣的可以參看一下其源碼。

*** TranslateService ***
import { Injectable } from "@angular/core";
// 引入語(yǔ)言配置和國(guó)際化文件文案對(duì)象
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層級(jí)取匹配改變量
  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;
  }
}

這樣,只需要在Pipe中調(diào)用Service的translate方法即可

*** 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);
  }
}

好了,現(xiàn)在我們處理邏輯已經(jīng)完全結(jié)束了,下面介紹一下如何使用

*** NG-ZORRO 控件 ***
 // 無(wú)動(dòng)態(tài)參數(shù)

... // 有動(dòng)態(tài)參數(shù)


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

以上流程基本上能滿(mǎn)足大部分angular項(xiàng)目的國(guó)際化需求,如果需要更加復(fù)雜的國(guó)際化情況,歡迎討論。

總結(jié)

Angular到5.0的國(guó)際化已經(jīng)相對(duì)來(lái)說(shuō)簡(jiǎn)便了很多,我們只需要在合適的地方打上i18n的tag即可方便快速地提取需要翻譯文案,具體如何處理翻譯后的文件因人而異,多種方法可幫助我們轉(zhuǎn)換(如本文通過(guò)nodejs)。

復(fù)雜一點(diǎn)的是無(wú)法通過(guò)打i18n標(biāo)簽來(lái)翻譯的文本,NG-ZORRO的國(guó)際化方案彌補(bǔ)了這方面的不足,結(jié)合起來(lái)可以很方便地完成項(xiàng)目的國(guó)際化。 國(guó)際化如果沒(méi)有專(zhuān)門(mén)的團(tuán)隊(duì)支持,翻譯難度很大,需要考慮的東西很多,比如繁體還有澳門(mén)繁體、臺(tái)灣繁體等,語(yǔ)法也不盡相同。

參考目錄

Angular的國(guó)際化(i18n)在線(xiàn)例子

NG-ZORRO Locale 國(guó)際化

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/90691.html

相關(guān)文章

  • 關(guān)于angular2.0的i18n國(guó)際化的解決方法,分享一下給大家,有錯(cuò)大家指出來(lái)互相學(xué)習(xí)哈。。。

    摘要:關(guān)于的,網(wǎng)上的資料也不多,剛好項(xiàng)目需要用到,就自己去查閱各種資料,自己整理了出來(lái),分享下出來(lái)給大家吧。 關(guān)于angular2的i18n,網(wǎng)上的資料也不多,剛好項(xiàng)目需要用到,就自己去查閱各種資料,自己整理了出來(lái),分享下出來(lái)給大家吧。廢話(huà)不多說(shuō)!直接上代碼: 首先我們肯定要新建一個(gè)文件,叫aaa(網(wǎng)上angular-cli教程很多),cmd打開(kāi)命令進(jìn)入到隨便一個(gè)目錄底下: ng new a...

    娣辯孩 評(píng)論0 收藏0
  • 關(guān)于angular2.0的i18n國(guó)際化的解決方法,分享一下給大家,有錯(cuò)大家指出來(lái)互相學(xué)習(xí)哈。。。

    摘要:關(guān)于的,網(wǎng)上的資料也不多,剛好項(xiàng)目需要用到,就自己去查閱各種資料,自己整理了出來(lái),分享下出來(lái)給大家吧。 關(guān)于angular2的i18n,網(wǎng)上的資料也不多,剛好項(xiàng)目需要用到,就自己去查閱各種資料,自己整理了出來(lái),分享下出來(lái)給大家吧。廢話(huà)不多說(shuō)!直接上代碼: 首先我們肯定要新建一個(gè)文件,叫aaa(網(wǎng)上angular-cli教程很多),cmd打開(kāi)命令進(jìn)入到隨便一個(gè)目錄底下: ng new a...

    alaege 評(píng)論0 收藏0
  • Angular 5.0 來(lái)了! 有這些大變化

    摘要:以下簡(jiǎn)單介紹的重大變化。狀態(tài)轉(zhuǎn)交及對(duì)的支持這樣更便于在服務(wù)端和客戶(hù)之間共享應(yīng)用狀態(tài)。狀態(tài)轉(zhuǎn)交的相關(guān)文檔幾周后會(huì)發(fā)布。我們刪除很多以前廢棄的如,也公布了一些新的廢棄項(xiàng)。以上指南會(huì)詳細(xì)介紹這些變更。已知問(wèn)題當(dāng)前已知與相關(guān)的問(wèn)題。 我們很高興地宣布Angular 5.0.0——五角形甜甜圈發(fā)布啦!這又是一個(gè)主版本,包含新功能并修復(fù)了很多bug。它再次體現(xiàn)了我們把Angular做得更小、更快、...

    張紅新 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

cncoder

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<