Защита приложения Angular 5 от неопределенной интерполяции массива в шаблоне - PullRequest
0 голосов
/ 27 апреля 2018

Я хочу добавить многоязычные возможности в приложение Angular 5, но я не уверен, что выбрал для него правильный подход.

Я определил в сервисе следующие 2 типа:

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 не может получить доступ к позиции 1 неопределенного .

Как я мог избежать этого потенциального риска? Заранее спасибо,

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Угловые шаблоны поддерживают оператор безопасной навигации (оператор Элвиса) для этой цели.

Он не поддерживается для скобочных обозначений , поэтому в этом случае необходима защита:

<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.

0 голосов
/ 27 апреля 2018

Вы можете написать как ниже:

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

Если MSGS['MSG_USER_BUTTTTTTTONS'] равно null или undefined - тогда код после && не будет выполнен, поэтому ошибка индекса не появится

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...