angular - 保护 Angular 5 应用程序免受模板中未定义数组插值的影响

标签 angular typescript

我想向 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/

相关文章:

javascript - 对复杂数据元素的引用

node.js - 在 Express js 中引导后获取连接

typescript - 特定属性上的深度/递归 Required<T>

angular - 我如何订阅可观察对象的 Angular 模型的变化?

angular - Mat Select 出现在页面底部

javascript - 如何在渲染后动态取消选中和选中 Nebular 复选框

angular - 引用错误 : IDBIndex is not defined Angular SSR

typescript - 如何检查 Typescript 编译问题?

html - 我的 Angular 应用程序中包含 css 的问题(不是 Angular cli)

angular - Angular `ngOnInit` 中的异步/等待