Angular.io describes the i18n tag as follows:
The Angular i18n attribute marks translatable content. Place it on every element tag whose fixed text is to be translated.
So my question is this. What if I have an element whose content is dynamic? Take for example this below table that shows a list of assets. The column, "Description" needs to be in some cases English, and in some cases some other language.
<table class="asset-table">
<thead>
<tr>
<th i18n="@@alarm-list-timeon">Time On</th>
<th i18n="@@alarm-list-timeoff">Time Off</th>
<th i18n="@@alarm-list-asset">Asset</th>
<th i18n="@@alarm-list-description">Description</th>
</tr>
</thead>
<tbody *ngIf="showAssets">
<tr *ngFor="let asset of pageItems">
<td>{{asset.timeon}}</td>
<td>{{asset.timeoff}}</td>
<td>{{asset.assetlabel}}</td>
<td i18n>{{asset.description}}</td>
</tr>
</tbody>
</table>
I was thinking something like this:
<table class="asset-table">
<thead>
<tr>
<th i18n="@@alarm-list-timeon">Time On</th>
<th i18n="@@alarm-list-timeoff">Time Off</th>
<th i18n="@@alarm-list-asset">Asset</th>
<th i18n="@@alarm-list-description">Description</th>
</tr>
</thead>
<tbody *ngIf="showAssets">
<tr *ngFor="let asset of pageItems">
<td>{{asset.timeon}}</td>
<td>{{asset.timeoff}}</td>
<td>{{asset.assetlabel}}</td>
<td i18n="@@{{asset.description}}">{{asset.description}}</td>
</tr>
</tbody>
</table>
...but I was mistaken. Any suggestions?
Angular.io describes the i18n tag as follows:
The Angular i18n attribute marks translatable content. Place it on every element tag whose fixed text is to be translated.
So my question is this. What if I have an element whose content is dynamic? Take for example this below table that shows a list of assets. The column, "Description" needs to be in some cases English, and in some cases some other language.
<table class="asset-table">
<thead>
<tr>
<th i18n="@@alarm-list-timeon">Time On</th>
<th i18n="@@alarm-list-timeoff">Time Off</th>
<th i18n="@@alarm-list-asset">Asset</th>
<th i18n="@@alarm-list-description">Description</th>
</tr>
</thead>
<tbody *ngIf="showAssets">
<tr *ngFor="let asset of pageItems">
<td>{{asset.timeon}}</td>
<td>{{asset.timeoff}}</td>
<td>{{asset.assetlabel}}</td>
<td i18n>{{asset.description}}</td>
</tr>
</tbody>
</table>
I was thinking something like this:
<table class="asset-table">
<thead>
<tr>
<th i18n="@@alarm-list-timeon">Time On</th>
<th i18n="@@alarm-list-timeoff">Time Off</th>
<th i18n="@@alarm-list-asset">Asset</th>
<th i18n="@@alarm-list-description">Description</th>
</tr>
</thead>
<tbody *ngIf="showAssets">
<tr *ngFor="let asset of pageItems">
<td>{{asset.timeon}}</td>
<td>{{asset.timeoff}}</td>
<td>{{asset.assetlabel}}</td>
<td i18n="@@{{asset.description}}">{{asset.description}}</td>
</tr>
</tbody>
</table>
...but I was mistaken. Any suggestions?
Share Improve this question edited Nov 12, 2017 at 1:25 Aravind 41.6k16 gold badges95 silver badges111 bronze badges asked Nov 10, 2017 at 22:39 Vinnie SalettoVinnie Saletto 3292 gold badges5 silver badges20 bronze badges 1- Angular i18n is static, not dynamic. – Ploppy Commented Nov 10, 2017 at 22:53
3 Answers
Reset to default 4First, the i18n value is an ID, so it would always be static.
Second, as far as translating content that changes, the only success I have had is a workaround using NgSwitch in the template.
In this example, thingStatus
is your variable, and its possible values are 'good', 'bad', and 'unknown'. All of these would each be a separate translation item, with its own i18n ID value.
Obviously, this would fail if thingStatus
could have an unmanageable number of possibilities.
<div [ngSwitch]="thingStatus">
<p *ngSwitchCase="good" i18n="status_good>Good</p>
<p *ngSwitchCase="bad" i18n="status_bad>Bad</p>
<p *ngSwitchCase="unknown" i18n="status_unknown>Unknown</p>
</div>
Use this construction
<span
i18n="status text|Status text@@statusText"
>{
asset.statusLangCode, select,
bad {Bad}
good {Good}
other {Unknown}
}</span>
And in translation file there will be generated a construct like this (target is added manually)
<source>{VAR_SELECT, select, good {Good} bad {Bad} other {Unknown}}</source>
<target>{VAR_SELECT, select, good {Хороший} bad {Плохой} other {Неизвестный}}</target>
For more info see https://angular.dev/guide/i18n/prepare#mark-alternates-and-nested-expressions
Assuming that your backend service returns known possible values, you can do the following:
const values = ['admin', 'teacher', 'librarian']
Add the translated values to sv_SE.json
given the previous values as keys
role: {
"admin": "admin",
"teacher": "lärare",
"librarian": "Bibliotekarie"
}
Call the translation in your app.ponent.html
<div *ngFor="let value of values">
{{ ('role.' + value) | translate }}
</div>