保护Angular 5 app免受模板

时间:2018-04-27 15:29:01

标签: 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可以& #39; t访问未定义的位置1。

我怎样才能避免这种潜在风险?提前谢谢,

2 个答案:

答案 0 :(得分:1)

您可以写如下:

MSGS['MSG_USER_BUTTTTTTTONS'] && MSGS['MSG_USER_BUTTTTTTTONS'][1]

如果MSGS['MSG_USER_BUTTTTTTTONS']nullundefined - 则&&之后的代码将无法执行 - 因此不会出现索引错误

答案 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