首页 > 解决方案 > 类型上不存在属性“VAR_PLURAL”

问题描述

使用 angular 8.x i18n 我遇到了一个非常模糊的错误消息问题(因为所有 i18n 错误消息往往都是;看着你,https://github.com/angular/angular-cli/issues/7555 #issuecomment-394228634)。

消息指出:ERROR in src/app/***.component.html(1,2): : Property 'VAR_PLURAL' does not exist on type '***Component'.

该错误仅正确说明了哪个文件受到影响,但行指示器是无意义的。使用二进制搜索,注释一半的 i18n 复数出现,我设法查明了麻烦制造者:

<ng-container i18n="@@playerCardinality">
  {singleTournament.tournament.teamSize.max, plural, =1 {player} other {players}}
</ng-container>

起初我认为问题可能是不同的 var name,因为它@@playerCardinality在整个应用程序的多个地方使用:

<ng-container i18n="@@playerCardinality">{ tournamentScreen.tournament.teamSize.max, plural, =1 {player} other {players} }</ng-container>
<ng-container i18n="@@playerCardinality">{ ladderScreen.ladder.teamSizeMax, plural, =1 {player} other {players} }</ng-container>

但其他也没有相同的变量名,到目前为止没有问题。

注释掉那些其他事件也解决了这个问题,所以它必须是它们之间的某种与交互相关的问题。

一定是一些平庸的问题,因为显然没有其他人遇到过类似的问题(基于谷歌结果)......

标签: angularinternationalizationangular-i18n

解决方案


我知道作者已经为自己找到了解决方案,但我将详细说明并列出更多可能发生此错误的场景以及如何修复它们。此修复也适用于 VAR_SELECT 和 VAR_PLURAL。因此,如果您看到此错误:ERROR in src/app/app.component.html(1,2): Property 'VAR_SELECT' does not exist on type 'AppComponent'.以下修复也应该对您有所帮助。

如果您有以下翻译:

<trans-unit id="PLURAL_TEST" datatype="html">
  <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
  <target>{VAR_PLURAL, plural, =0 {à l'instantt} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
</trans-unit>

并想在你的 html 中使用它,你会做这样的事情:

<p i18n="@@PLURAL_TEST">{minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>

但是,如果您在 html 的 {minutes,plural ...} } 部分之前或之后有一些字符,它将失败并且您将看到以下错误: ERROR in src/app/app.component.html(1,8): Property 'VAR_PLURAL' does not exist on type 'AppComponent'.

这意味着以下所有 html 值都将失败:

<p i18n="@@PLURAL_TEST"> {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>
<p i18n="@@PLURAL_TEST">{minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} } </p>
<p i18n="@@PLURAL_TEST">
{minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }
</p>

第一个开头有空格,第二个结尾有空格,第三个有换行符。第三个是原始海报的一个例子。您可以用任何字符、单词、插值等替换空格,它总是会失败。即使您更改 .xlf 文件中的翻译以匹配 html,它仍然会失败。例如:

xlf:

<trans-unit id="PLURAL_TEST" datatype="html">
  <source> {VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
  <target> {VAR_PLURAL, plural, =0 {à l'instantt} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
</trans-unit>

html:

<p i18n="@@PLURAL_TEST"> {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>

还是会失败。即使在翻译和 html 中存在前导空格。

如果您确实想将 VAR_PLURAL 或 VAR_SELECT 翻译嵌套在另一个翻译中,那么您应该使用<x id="ICU" />标签来实现这一点。

因此,如果我想在我的 html 中使用它:

<p>Hello, {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>

我需要定义两种翻译,一种用于文本的 VAR_PLURAL 或 VAR_SELECT 部分。我们将其称为内部翻译。我们还需要对文本的其余部分(在这种情况下是Hello,部分)进行另一种翻译,这将是外部翻译。所以我的翻译文件将如下所示:

<trans-unit id="PLURAL_TEST_OUTER" datatype="html">
  <source>Hello, <x id="ICU" /></source>
  <target>Bonjour, <x id="ICU" /></target>
</trans-unit>

<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
  <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" /> minutes ago} }</source>
  <target>{VAR_PLURAL, plural, =0 {à l'instantt} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
</trans-unit>

请注意,内部表达式的 trans-id 必须是自动生成的(在https://github.com/angular/angular/issues/26379中查看更多信息)。

我的 html 将如下所示:

<p i18n="@@PLURAL_TEST_OUTER">Hello, {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>

您可以在此处找到有关嵌套翻译的更多信息 - https://angular.io/guide/i18n#translate-a-nested-expression

所以总而言之,如果你看到这个问题:

  1. 在 html 中的 VAR_PLURAL 或 VAR_SELECT 语句之前或之后检查空格、字符或插值。如果它不应该在那里,请删除它。
  2. 如果它应该在那里,请确保您正确地将翻译嵌套在 .xlf 文件中。

推荐阅读