我想为Angular 5应用添加多语言功能,但我不确定我是否选择了正确的方法。
我在服务中定义了这两种类型:
type appMsgTuple = {
[key : string] : string | string[]
}
type appMsgs = {
es : appMsgTuple,
en : appMsgTuple
}
因此,我定义变量来保存应用程序的不同组件的翻译,如:
export var MSG_USER : appMsgs = {
"es" : {
"MSG_USER_1" : "Por favor, introduzca sus datos de acceso",
"MSG_USER_BUTTONS" : [ "ACCEDER", "Síganos" ]
},
"en" : {
"MSG_USER_1" : "Please, type your login details",
"MSG_USER_BUTTONS": [ "LOGIN", "Follow us"]
}
}
在每个组件中,我从服务中导入相应的字符串:
// USER COMPONENT
[ ... ]
import { MSG_USER } from 'app/services/languages.service';
public MSGS : any = {}; // We'll use this to 'point' to the right language in MSG_USER (see below)
并且,为了使其更简洁,我将变量MSGS
分配给正确的语言(由用户选择),如下所示:
// USER COMPONENT
[ ... ]
ngOnInit() {
this.MSGS = MSG_USER[selUsr.selectedLanguage];
[ ... ]
}
最后,在模板中,我使用MSGS
变量以这种方式显示不同的字符串:
<h5 class="fwcBlue">{{ MSGS['MSG_USER_1'] }}</h5>
<button label="{{ MSGS['MSG_USER_BUTTONS'][1] }}" [disabled]="!formModel.valid || formModel.pristine" (click)="onLogin()">
</button>
这很有效,但是它有一个很大的问题:如果我输错任何键(例如,我键入MSGS['MSG_USER_BUTTTTTTTONS'][1]
),应用程序崩溃,因为它不存在,Javascript可以& #39; t访问未定义的位置1。
我怎样才能避免这种潜在风险?提前谢谢,
答案 0 :(得分:1)
您可以写如下:
MSGS['MSG_USER_BUTTTTTTTONS'] && MSGS['MSG_USER_BUTTTTTTTONS'][1]
如果MSGS['MSG_USER_BUTTTTTTTONS']
为null
或undefined
- 则&&
之后的代码将无法执行 - 因此不会出现索引错误
答案 1 :(得分:1)
Angular模板为此目的支持safe navigation operator(Elvis运营商)。
isn't supported for bracket notation,因此在这种情况下需要保护措施:
<button
*ngIf="MSGS['MSG_USER_BUTTONS']"
label="{{ MSGS['MSG_USER_BUTTONS'][1] }}"
[disabled]="!formModel.valid || formModel.pristine" (click)="onLogin()"
>
</button>
由于这个原因,元组不是一个很好的选择。键值对不会出现这样的问题:
"es" : {
"MSG_USER_1" : "Por favor, introduzca sus datos de acceso",
"MSG_USER_BUTTONS" : { ACCEDER: Síganos }
}
提供一个不需要直接访问消息对象的抽象是有益的 - 一个服务和一个管道,它将返回一个正在使用的语言和指定路径的值,如{{ 'MSG_USER_BUTTONS.LOGIN' | translate }}
,这是怎么回事通常都会完成。有几种现有的i18n解决方案使用这种方法,例如ngx-translate