@actra-development-oss/ng-i18n-aot-loader 中文文档教程
ng-i18n-aot-loader [Proof-Of-Concept]
用于 webpack 2 的 angular i18n 预加载器支持具有动态区域设置更改
的 AOT 当使用 AOT 构建 angular 时,在撰写本文时,需要将应用程序构建为每个区域设置的单独包。
为了避免这个“问题”,您可以使用这个预加载器,直到 Angular 团队实施了一个干净的解决方案。
What it does
加载程序在应用程序的 HTML 被传递给 Angular 的编译器之前修改它,方法是为每个语言环境呈现它并将所有翻译包装到 ng-container
s 中。
如果您在模板中使用 ng-content
或 router-outlet
,它们将被过滤掉并替换为注入到 HTML 末尾的模板引用,因为它们可能只每发生一次 文档,但在修改后会出现多次(您的语言环境数 + 1)。
所有绑定和上下文都保持不变,无需对您的代码施展特殊魔法。
要实际更改显示的语言环境,提供了一项服务(由 @actra-development-oss/ng- i18n-aot-module),您可以将其包含在您的组件中以对其调用 setLocale('new_locale')
。
JIT and AOT
加载程序适用于 JIT 和 AOT 构建,因此也适用于热模块替换。
请记住,当更改模板中的可翻译文本时,您必须在消息 ID 更改时再次提取翻译。
不使用此加载程序时也是如此 - 这是 Angular 计算消息 ID 的方式。
所以这个过程是:change html
=> 提取文本
=> 更新翻译
=> 重建 html
。
根据您的开发设置,webpack 可能会在翻译文件更改时自动为您重建 HTML。
如果没有,您可以通过更新所需的文件(例如添加新行,并将其保存以供 webpack 捕获更改)来触发单个文件的 HTML 重建。
Demo
一个简单的演示托管在一个单独的存储库中:https://github.com/actra-development-oss/ng-i18n-aot-demo
演示页面:https://actra-development-oss.github.io/ng-i18n-aot-demo/
Example
鉴于此(部分)来源:
<div class="mat-app-background">
<ng-content></ng-content>
<md-chip-list>
<md-chip i18n>First chip</md-chip>
<md-chip color="primary" i18n i18n-title="Second chip title" title="Second chip :-)">Second chip</md-chip>
<md-chip color="accent" i18n>Third chip</md-chip>
</md-chip-list>
<router-outlet></router-outlet>
</div>
加载程序将产生此结果,给定一个语言环境“de-DE”翻译文件:
<ng-container *ngI18nAot="'automaticallyGeneratedUniqueIdPerHtmlFile'; locale: 'de-DE'">
<div class="mat-app-background">
<ng-container *ngTemplateOutlet="automaticallyGeneratedTemplate1"></ng-container>
<md-chip-list>
<md-chip>Erster Chip</md-chip>
<md-chip color="primary" title="Zweiter Chip :)">Zweiter Chip</md-chip>
<md-chip color="accent">Dritter Chip</md-chip>
</md-chip-list>
<ng-container *ngTemplateOutlet="automaticallyGeneratedTemplate2"></ng-container>
</div>
</ng-container>
<ng-container *ngI18nAot="'automaticallyGeneratedUniqueIdPerHtmlFile'; isDefault: true">
<div class="mat-app-background">
<ng-container *ngTemplateOutlet="automaticallyGeneratedTemplate1"></ng-container>
<md-chip-list>
<md-chip>First chip</md-chip>
<md-chip color="primary" title="Second chip :-)">Second chip</md-chip>
<md-chip color="accent">Third chip</md-chip>
</md-chip-list>
<ng-container *ngTemplateOutlet="automaticallyGeneratedTemplate2"></ng-container>
</div>
</ng-container>
<ng-template #automaticallyGeneratedTemplate1><ng-content></ng-content></ng-template>
<ng-template #automaticallyGeneratedTemplate2><router-outlet></router-outlet></ng-template>
Compatibility to angular syntax and tools
无需学习任何新语法或工具。
加载程序使用普通的角度 i18n 语法,因此只需使用 i18n
或 i18n-
属性标记您的 HTML,就像您在任何常规角度 2 / 4 应用程序中所做的那样.
您还可以使用例如来自 angular-cli 的 ng-xi18n 工具来生成翻译源。
How to use it
安装包 npm install @actra-development-oss/ng-i18n-aot-loader @actra-development-oss/ng-i18n-aot-module
并将加载器定义为预加载器您的 webpack 配置:
module: {
rules: [
{
enforce: 'pre',
test: /\.html$/,
use: [
{
loader: '@actra-development-oss/ng-i18n-aot-loader',
options: {
enabled: true,
translationFiles: ['/path/to/src/locales/messages.de.xlf'],
translationFormat: 'xliff'
}
}
],
include: [
'/path/to/src'
],
exclude: [
'/path/to/src/index.html'
]
},
// your other loaders...
]
}
将模块包含到您的应用程序主模块中:
import { NgI18nAotModule } from '@actra-development-oss/ng-i18n-aot-module';
// ...
@NgModule({
// ...
imports: [
NgI18nAotModule.forRoot(),
// ...
],
// ...
})
@Injectable()
export class ApplicationModule {
// ...
}
将模块包含到 a) 使用翻译的每个模块 OR b) 一次包含在所有模块中的共享模块中。
代码显示选项 b),包含在共享模块中:
import { NgI18nAotModule } from '@actra-development-oss/ng-i18n-aot-module';
// ...
@NgModule({
// ...
exports: [
NgI18nAotModule,
// ...
],
// ...
})
export class SharedModule {
}
要实际更改显示的语言环境,请使用该服务:
import { NgI18nAotService } from '@actra-development-oss/ng-i18n-aot-module';
@Component({
// ...
template: `
<button (click)="setLocale('en_US')">en_US</button> <button (click)="setLocale('de_DE')">de_DE</button><br />
Current locale: {{locale}}
`
})
export class MyComponent {
public locale: string;
constructor(protected ngI18nAotService: NgI18nAotService) {
this.locale = this.ngI18nAotService.getLocale();
}
public setLocale(locale: string): void {
this.locale = locale;
this.ngI18nAotService.setLocale(this.locale);
}
}
Options
Option | Type | Explanation |
---|---|---|
enabled | boolean | Whether the loader should modify the HTML or not. |
translationFiles | string[] | Paths of all your locale files to render. |
translationFormat | string | Format of the translation files as used by angular: xlf / xliff, xlf2 / xliff2, xmb, xtb |
ng-i18n-aot-loader [Proof-Of-Concept]
angular i18n pre-loader for webpack 2 to support AOT with dynamic locale changes
When building angular with AOT, at the time of writing, applications need to be built as separate bundles for each locale.
To circumvent this "problem" you may use this pre-loader until the angular team has implemented a clean solution.
What it does
The loader modifies the application's HTML before it get's passed to angular's compiler by rendering it for each locale and wrapping all translations into ng-container
s.
If you're using ng-content
or router-outlet
inside your templates those get filtered out and replaced by a template reference injected to the end of the HTML because they may only occur once per document but would occur multiple times (your number of locales + 1) after modification.
All bindings and contexts stay intact and there's no need to do special magic to your code.
To actually change the displayed locale, a service is provided (by @actra-development-oss/ng-i18n-aot-module) that you may include in your component(s) to call setLocale('new_locale')
on it.
JIT and AOT
The loader works for both JIT and AOT builds and thus also with hot module replacement.
Just keep in mind that when changing translatable texts inside your templates you have to extract the translations again as their message ids change.
This is also true when not using this loader - it's the way angular calculates the message ids.
So the process would be: change html
=> extract texts
=> update translations
=> rebuild html
.
Depending on your dev setup webpack may do the HTML rebuild automatically for you when the translation files change.
If not you can trigger a HTML rebuild for individual files simply by updating the desired file, e.g. adding a new-line, and saving it for webpack to catch the change.
Demo
A simple demo is hosted in a separate repository: https://github.com/actra-development-oss/ng-i18n-aot-demo
Demo page: https://actra-development-oss.github.io/ng-i18n-aot-demo/
Example
Given this (partial) source:
<div class="mat-app-background">
<ng-content></ng-content>
<md-chip-list>
<md-chip i18n>First chip</md-chip>
<md-chip color="primary" i18n i18n-title="Second chip title" title="Second chip :-)">Second chip</md-chip>
<md-chip color="accent" i18n>Third chip</md-chip>
</md-chip-list>
<router-outlet></router-outlet>
</div>
The loader would produce this result, given one locale "de-DE" translation file:
<ng-container *ngI18nAot="'automaticallyGeneratedUniqueIdPerHtmlFile'; locale: 'de-DE'">
<div class="mat-app-background">
<ng-container *ngTemplateOutlet="automaticallyGeneratedTemplate1"></ng-container>
<md-chip-list>
<md-chip>Erster Chip</md-chip>
<md-chip color="primary" title="Zweiter Chip :)">Zweiter Chip</md-chip>
<md-chip color="accent">Dritter Chip</md-chip>
</md-chip-list>
<ng-container *ngTemplateOutlet="automaticallyGeneratedTemplate2"></ng-container>
</div>
</ng-container>
<ng-container *ngI18nAot="'automaticallyGeneratedUniqueIdPerHtmlFile'; isDefault: true">
<div class="mat-app-background">
<ng-container *ngTemplateOutlet="automaticallyGeneratedTemplate1"></ng-container>
<md-chip-list>
<md-chip>First chip</md-chip>
<md-chip color="primary" title="Second chip :-)">Second chip</md-chip>
<md-chip color="accent">Third chip</md-chip>
</md-chip-list>
<ng-container *ngTemplateOutlet="automaticallyGeneratedTemplate2"></ng-container>
</div>
</ng-container>
<ng-template #automaticallyGeneratedTemplate1><ng-content></ng-content></ng-template>
<ng-template #automaticallyGeneratedTemplate2><router-outlet></router-outlet></ng-template>
Compatibility to angular syntax and tools
There's no need to learn any new syntax or tools.
The loader uses plain angular i18n-syntax, so just tag your HTML with i18n
or i18n-<attributeName>
attributes as you would do in any regular angular 2 / 4 app.
You can also still use e.g. the ng-xi18n tool from angular-cli to generate the translation sources.
How to use it
Install the packages npm install @actra-development-oss/ng-i18n-aot-loader @actra-development-oss/ng-i18n-aot-module
and define the loader as a pre-loader in your webpack config:
module: {
rules: [
{
enforce: 'pre',
test: /\.html$/,
use: [
{
loader: '@actra-development-oss/ng-i18n-aot-loader',
options: {
enabled: true,
translationFiles: ['/path/to/src/locales/messages.de.xlf'],
translationFormat: 'xliff'
}
}
],
include: [
'/path/to/src'
],
exclude: [
'/path/to/src/index.html'
]
},
// your other loaders...
]
}
Include the module into your applications main module:
import { NgI18nAotModule } from '@actra-development-oss/ng-i18n-aot-module';
// ...
@NgModule({
// ...
imports: [
NgI18nAotModule.forRoot(),
// ...
],
// ...
})
@Injectable()
export class ApplicationModule {
// ...
}
Include the module into a) every module that uses translations OR b) once into your shared module that is included in all your modules.
Code shows option b), include in shared module:
import { NgI18nAotModule } from '@actra-development-oss/ng-i18n-aot-module';
// ...
@NgModule({
// ...
exports: [
NgI18nAotModule,
// ...
],
// ...
})
export class SharedModule {
}
To actually change the displayed locale use the service:
import { NgI18nAotService } from '@actra-development-oss/ng-i18n-aot-module';
@Component({
// ...
template: `
<button (click)="setLocale('en_US')">en_US</button> <button (click)="setLocale('de_DE')">de_DE</button><br />
Current locale: {{locale}}
`
})
export class MyComponent {
public locale: string;
constructor(protected ngI18nAotService: NgI18nAotService) {
this.locale = this.ngI18nAotService.getLocale();
}
public setLocale(locale: string): void {
this.locale = locale;
this.ngI18nAotService.setLocale(this.locale);
}
}
Options
Option | Type | Explanation |
---|---|---|
enabled | boolean | Whether the loader should modify the HTML or not. |
translationFiles | string[] | Paths of all your locale files to render. |
translationFormat | string | Format of the translation files as used by angular: xlf / xliff, xlf2 / xliff2, xmb, xtb |