如何在Angular 5中设计键值对属性文件?
当然可以在Angular 5里实现类似JSF的键值对属性文件方案,完全不用被官方冗长的xlf格式束缚!下面给你两种实用的实现思路,和你之前的用法逻辑高度匹配:
方案一:自定义服务加载JSON属性文件
这是最贴合你JSF使用习惯的方式,完全自己掌控逻辑:
- 先创建键值对格式的JSON属性文件,比如放在
assets/i18n/en.json:
{ "company.trip.HOLIDAY.name": "Holiday trip type", "company.trip.BUSINESS.name": "Business trip type" }
- 编写一个翻译服务
translation.service.ts,负责加载和读取属性:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/map'; @Injectable() export class TranslationService { private translations: any; constructor(private http: HttpClient) {} // 加载指定语言的属性文件,默认加载英文 loadTranslations(lang: string = 'en'): Observable<any> { return this.http.get(`assets/i18n/${lang}.json`) .map(data => { this.translations = data; return data; }); } // 根据键获取对应文本,找不到则返回键本身 get(key: string): string { return this.translations?.[key] || key; } }
- 在
app.module.ts里注册服务,并让应用初始化时就加载属性文件:
import { APP_INITIALIZER } from '@angular/core'; import { TranslationService } from './translation.service'; // 初始化函数,确保应用启动前加载翻译文件 export function initTranslation(service: TranslationService) { return () => service.loadTranslations(); } @NgModule({ // ...其他模块配置 providers: [ TranslationService, { provide: APP_INITIALIZER, useFactory: initTranslation, deps: [TranslationService], multi: true } ] }) export class AppModule {}
- 自定义管道简化模板使用(类似JSF里的表达式):
创建translate.pipe.ts:
import { Pipe, PipeTransform } from '@angular/core'; import { TranslationService } from './translation.service'; @Pipe({ name: 'translate' }) export class TranslatePipe implements PipeTransform { constructor(private translationService: TranslationService) {} transform(key: string): string { return this.translationService.get(key); } }
然后在模板里就能像JSF那样使用了:
<!-- 直接使用固定键 --> <p>{{ 'company.trip.HOLIDAY.name' | translate }}</p> <!-- 动态拼接键,和你JSF里的strcat逻辑一致 --> <p>{{ 'company.trip.' + trip.type + '.name' | translate }}</p>
方案二:用第三方库快速实现
如果不想自己写底层逻辑,可以用成熟的第三方库ngx-translate(完全兼容Angular 5),它天生就是基于键值对的翻译方案:
- 安装对应版本的依赖(要匹配Angular 5的版本):
npm install @ngx-translate/core@9.1.1 @ngx-translate/http-loader@2.0.1 --save
- 在
app.module.ts里配置库:
import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import { HttpClient } from '@angular/common/http'; // 配置属性文件的加载路径 export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); } @NgModule({ imports: [ // ...其他模块 TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }) ] }) export class AppModule {}
- 模板里直接使用,和自定义方案的用法几乎一致:
<p>{{ 'company.trip.HOLIDAY.name' | translate }}</p> <p>{{ 'company.trip.' + trip.type + '.name' | translate }}</p>
它还支持更灵活的参数替换,比如属性文件里有占位符时:
{ "company.trip.desc": "{{type}} trip (duration: {{days}} days)" }
模板里可以这样传参:
<p>{{ 'company.trip.desc' | translate: {type: trip.type, days: trip.duration} }}</p>
额外提示
- 两种方案都支持多语言切换,只需要加载对应语言的JSON文件即可。
- 自定义方案可以根据需求扩展
get方法,比如添加默认值、支持嵌套键解析等。 - 确保属性文件放在Angular能访问的目录下(默认
assets文件夹是可访问的)。
内容的提问来源于stack exchange,提问作者user2304483
相关产品推荐
相关产品推荐

