Angular $localize 使用动态翻译 ID

Angular $localize using dynamic translation ID

有了新的 Angular 9 @angular/localize 现在可以直接从打字稿翻译代码。 由于它的用法没有正式记录,我找到了一些提示 on this post.

$localize`:@@my-trans-unit-id:` // IT WORKS

当 ID 直接传递给函数时,它可以正常工作,但如果我希望 ID 是动态的(并传递一个变量),它就不起作用,在不解析或翻译的情况下呈现 ID。

我尝试通过这种方式传递变量:

const id = "my-trans-unit-id";

$localize`:@@${id}:`; // NOT WORKING
$localize`:@@`+id+`:`; // NOT WORKING

Angular 不提供任何生成动态翻译的机制,因为它们是在编译时生成的。

我最终创建了管道并在每次需要翻译时调用它们。我没有使用 1 条独特的指令来翻译字符串,而是在一个开关中使用多个 $localize 调用以 return 通过 ID 进行正确的翻译。

这是一个翻译订单状态的例子,可以在运行时调用:

import { Pipe, PipeTransform } from '@angular/core';
import { OrderStatusEnum } from 'installation-status.enum';

@Pipe({
    name: 'orderStatusRenderer'
})
export class OrderStatusRendererPipe implements PipeTransform {
    constructor() {}

    transform(value: number, ...args: any[]): any {
        switch (value) {
            case OrderStatusEnum.PREPARING:
                return $localize`:@@order.status.preparing:`;
            case OrderStatusEnum.SHIPPED:
                return $localize`:@@order.status.shipped:`;
            case OrderStatusEnum.COMPLETED:
                return $localize`:@@order.status.completed:`;
        }
    }
}

这有效。

不要让我解释,这是我摸索出来的:

const localize = $localize;
const id = "my-trans-unit-id";
const translation = localize(<any>{ '0': `:@@${id}:${id}`, 'raw': [':'] });

您可以创建自己的 tagged templates 函数来处理跨单元 ID 的转换:

const transUnitId = '@@Messages.Greeting';
const name = 'Joe';
const message = $localizeId`${transUnitId}:TRANSUNITID:Hi ${name}:NAME:, translated with run-time created trans-unit id.`;
// Original
// message = Hi Joe, translated with run-time created trans-unit id.
// German
// message = Hallo Joe, übersetzt mit einer zur Laufzeit erstellten Trans-Unit-Id.
export function $localizeId(messageParts: TemplateStringsArray, ...expressions: any[]): string {
  // Create writeable copies
  const messagePartsCopy: any = [...messageParts];
  const messagePartsRawCopy = [...messageParts.raw];

  // Strip trans-unit-id element
  const prefix = messagePartsCopy.shift();
  const prefixRaw = messagePartsRawCopy.shift();
  const transUnitId = expressions.shift();

  // Re-add prefix and replace :TRANSUNITID: with transUnitId.
  messagePartsCopy[0] = prefix + messagePartsCopy[0].replace(':TRANSUNITID:', `:@@${transUnitId}:`);
  messagePartsRawCopy[0] = prefixRaw + messagePartsRawCopy[0].replace(':TRANSUNITID:', `:${transUnitId}:`);

  // Create messageParts object
  Object.defineProperty(messagePartsCopy, 'raw', {value: messagePartsRawCopy});

  // Call original localize function
  return $localize(messagePartsCopy as TemplateStringsArray, ...expressions);
}