咨询Angular 4中AOT模式下i18n仅支持模板翻译的含义及本地化示例
一、AOT模式下i18n仅支持模板翻译的具体含义
Angular 4的AOT(提前编译)i18n机制,是在编译阶段就把模板中的翻译文本替换成目标语言,生成对应语言的静态编译包。但在Angular 4时代,这个机制有个明确局限:只能识别并处理组件模板(.html文件)中通过i18n属性标记的文本,对于组件类文件(.ts)里的硬编码字符串,官方的AOT i18n无法直接处理——因为AOT编译时不会扫描类文件里的文本,这些内容是运行时才执行的,没法提前替换成翻译后的内容。
二、示例说明
1. 模板中可正常翻译的场景
比如你有一个app.component.html模板:
<h1 i18n="@@welcomeHeader">Welcome to our app!</h1> <p i18n="@@welcomeDesc">This is a sample Angular 4 app with i18n support.</p>
这里用i18n属性标记了需要翻译的文本,还加了@@xxx的自定义ID方便管理翻译。
接下来执行提取命令生成翻译源文件:
ng-xi18n --output-path src/locale
会得到messages.xlf文件,你可以复制它改成messages.zh.xlf,然后把对应文本翻译成中文:
<trans-unit id="welcomeHeader" datatype="html"> <source>Welcome to our app!</source> <target>欢迎来到我们的应用!</target> </trans-unit> <trans-unit id="welcomeDesc" datatype="html"> <source>This is a sample Angular 4 app with i18n support.</source> <target>这是一个支持国际化的Angular 4示例应用。</target> </trans-unit>
之后配置编译选项生成中文包,运行时就会显示翻译后的文本——这就是AOT模板翻译的正常流程。
2. 类文件中无法被AOT i18n处理的场景
如果你的app.component.ts里有这样的代码:
export class AppComponent { message = 'Hello, User!'; // 这个硬编码文本无法被AOT i18n识别 }
然后模板里绑定这个变量:
<p>{{ message }}</p>
即使你在模板里给这个<p>加i18n属性也没用,因为message的值是类里的硬编码字符串,AOT编译时不会处理类中的变量值,所以不管你怎么配置翻译,运行时都会显示Hello, User!,没法自动翻译成其他语言。
三、适配浏览器语言环境的优质实现示例
下面是一个完整的、基于Angular 4 AOT的i18n实现,能自动检测浏览器语言并加载对应语言包:
1. 标记模板文本
确保所有需要翻译的文本都在模板里用i18n标记好(参考前面的示例)。
2. 配置多语言编译
修改angular-cli.json,在apps数组里添加多语言配置:
{ "apps": [ { "root": "src", "outDir": "dist", // ...其他默认配置 "i18n": { "sourceLocale": "en", "locales": { "zh": "src/locale/messages.zh.xlf", "fr": "src/locale/messages.fr.xlf" } } } ] }
3. 编译多语言包
执行命令编译不同语言的静态包:
# 编译英文包(默认) ng build --prod --aot # 编译中文包 ng build --prod --aot --locale zh --i18n-format xlf --output-path dist/zh # 编译法文包 ng build --prod --aot --locale fr --i18n-format xlf --output-path dist/fr
编译后dist目录下会有en、zh、fr三个文件夹,对应不同语言的编译产物。
4. 编写语言检测与跳转逻辑
在项目根目录创建index.html的副本index.i18n.html,添加检测浏览器语言的脚本:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Angular 4 i18n Demo</title> <base href="/"> </head> <body> <script> // 提取浏览器首选语言的前两位(比如zh-CN取zh,fr-FR取fr) const browserLang = navigator.language.split('-')[0]; // 定义支持的语言列表 const supportedLangs = ['en', 'zh', 'fr']; // 确定最终要加载的语言,默认回退到英文 const targetLang = supportedLangs.includes(browserLang) ? browserLang : 'en'; // 跳转到对应语言的编译包路径 window.location.href = `/${targetLang}/`; </script> </body> </html>
然后把原来的index.html重命名为index.en.html,再将index.i18n.html改名为index.html。这样用户访问根路径时,会先检测浏览器语言,自动跳转到对应语言的版本。
5. 测试运行
把dist目录部署到服务器,访问根路径即可:中文浏览器会自动跳转到/zh/显示中文界面,法文浏览器跳转到/fr/显示法文界面,未支持的语言则默认显示英文。
内容的提问来源于stack exchange,提问作者nee2610

