我想向 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 无法访问 undefined 的位置 1。
如何避免这种潜在风险?提前致谢,
最佳答案
Angular 模板支持 safe navigation operator (Elvis 运算符(operator))用于此目的。
它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' |翻译}}
,这就是通常的做法。有几个现有的 i18n 解决方案使用这种方法,例如ngx-translate
.
关于angular - 保护 Angular 5 应用程序免受模板中未定义数组插值的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50065690/