问题描述
我正在使用ngx-translate构建一个有角度的应用程序。运行良好。现在,我开始从后端(firebase)获得数据,为此我将进行翻译。
从模型显示本地化数据的正确方法是什么?我尚未确定数据格式,所以要么是这样:
{
'title_fr': 'mon titre','title_en': 'my title','title_de': 'mein Titel','description_fr' : '....'
//...
}
类似于:
{
title: {'fr':'mon titre','en': 'my title','de': 'mein Titel'}
description: { 'fr': 'ma description',/*...*/}
}
我不确定如何显示它们:
- 我将在
ngFor
上重复观察这些项目,如果可以避免必须映射每个数据,那将很棒 - 更改语言时,我还需要显示正确的翻译
您会推荐我什么?
解决方法
如果您能够定义可以从后端获取的数据,那么您可以按照以下方式构建数据结构,
{
"dataLocalization": [{
"locale": "fr","title": "mon titre","description":"ma description"
},{
"locale": "en","title": "my title","description":"my description"
}]
}
然后您可以通过数组dataLocalization中的findIndex方法找到您的语言环境,并使用其标题和描述值
,@ngx-translate/http-loader库允许使用http加载翻译。
下面是我在开发的应用程序中如何将ngx-translate
与http-loader
一起使用的一个示例。
我已经在下面的代码中制作了stackblitz(可用here):
定义i18n字符串的数据结构
在该示例中,每种语言都有一个URL,可以按以下格式检索翻译数据(json
):
{
welcome: "Welcome",subscription_msg: "Subscribe now"
}
为每种受支持的语言创建一个Web服务
考虑一个支持3种语言的应用程序:en
,pt
和fr
。
我通常每种语言都有一个网址。每个网址都返回一个key
-value
对的json,其中的键是我在前端使用的标签,而值是我要向用户显示该语言的消息。
在该示例中,我创建了3个模拟URL,每种语言的翻译如下:
英语-模拟网址:https://run.mocky.io/v3/33f736b0-e73a-499e-8a50-01e66041d634
{
welcome: "Welcome",subscription_msg: "Subscribe now"
}
葡萄牙语-模拟网址:https://run.mocky.io/v3/db1e37da-342e-4918-8ce2-bd30aa12fe79
{
welcome: "Bem-vindo",subscription_msg: "Inscreva-se gratuitamente"
}
法语-模拟网址:https://run.mocky.io/v3/6960c960-ea66-42a0-87f1-f34568ecb740
{
welcome: "Bienvenue",subscription_msg: "Abbonez-vous"
}
要在前端输出subscription_msg
,我将使用ngx-translate
语法,如下所示:
{{ 'subscription_msg' | translate}}
安装@ ngx-translate / http-loader
假设已经安装了ngx-translate
,这是用于安装http-loader
的命令:
npm install @ngx-translate/http-loader --save
创建自己的TranslationLoader
我们需要实现TranslationLoader
接口。它只有一种方法(getLanguage()
)负责为当前语言加载i18n消息的映射。
下面是我们称为TranslationHttpLoader
的简单实现。更改语言时将调用它:
export class TranslationHttpLoader implements TranslateLoader {
constructor(private httpClient: HttpClient) {}
public getTranslation(lang: string): Observable<Object> {
if (lang == null) {
lang == "en";
}
let urls = {
en: "https://run.mocky.io/v3/33f736b0-e73a-499e-8a50-01e66041d634",pt: "https://run.mocky.io/v3/db1e37da-342e-4918-8ce2-bd30aa12fe79",fr: "https://run.mocky.io/v3/6960c960-ea66-42a0-87f1-f34568ecb740"
};
let observer = new Observable(observer => {
this.httpClient.get(urls[lang]).subscribe(
data => {
observer.next(data);
observer.complete();
}
);
});
return observer;
}
}
配置翻译提供商
在app.module.ts
中,我们应该定义一个HttpLoaderFactory
:
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslationHttpLoader(httpClient);
}
并将其与提供的TranslateLoader
关联:
@NgModule({
imports: [
BrowserModule,FormsModule,HttpClientModule,TranslateModule.forRoot({
loader: {
provide: TranslateLoader,useFactory: HttpLoaderFactory,deps: [HttpClient]
}
})
],declarations: [AppComponent],bootstrap: [AppComponent]
})
export class AppModule {}
测试-更改语言并显示本地化消息
要测试
- 我们创建了一个简单的组件,该组件具有一个
<select>
(将语言作为选项)和一个(change)
事件处理程序。 - 要输出本地化的字符串,我们使用
ngx-translate
语法{{ 'key_in_json_file' | translate }}
。
app.component.html
<div>
<label>Language</label>
<select (change)="changeLanguage($event)">
<option value="en">English</option>
<option value="pt">Português</option>
<option value="fr">Français</option>
</select>
<p>
{{'welcome' | translate}}.
</p>
<p>
{{'subscription_msg' | translate}}
</p>
</div>
(change)
事件发生时,我们要做的就是调用translate.use(lang)
。我们的加载程序将在提供的网址中检索所选语言的数据,并将其提供给ngx-translate
:
app.component.ts
export class AppComponent {
defaultLang: string = "en";
constructor(private translateService: TranslateService) {}
ngOnInit() {
this.translateService.use(this.defaultLang);
}
changeLanguage(event) {
let lang = (event.target as HTMLInputElement).value;
this.translateService.use(lang);
}
}
输出预览
下一步
可以通过此处提供的代码进行某些增强,例如:
- 使用
translateService.getBrowserLang()
在用户首次访问时检测浏览器语言
- 将用户当前语言存储在本地存储或其他持久存储中。
- 适应
TranslationHttpLoader
,以便它可以使用每种语言的默认令牌脱机工作(在移动应用程序中尤其有用)。
可以在此堆叠闪电战中看到上面描述的代码:https://stackblitz.com/edit/angular-ivy-pwcrvy?file=src/app/translation-http-loader.ts