Internationalisierung fĂĽr Angular, Teil 2: ngx-translate
Seite 2: Datenquelle, Direktiven und Pipes
Damit die Bibliothek anhand der Sprach-ID Sprachdateien laden kann, bezieht sie die Übersetzungsdaten über einen TranslateLoader. Er ist innerhalb der Methode TranslateModule.forRoot zu konfigurieren. Standardmäßig wird dafür der HTTP-Loader von ngx-translate genutzt, den man zusätzlich installieren muss:
npm install @ngx-translate/http-loader --save
Im folgendem Codeauszug ist zu sehen, dass der Provider TranslateLoader eine eigene Factory erhält, die den Loader TranslateHttpLoader über die Methode createTranslateLoader zurückliefert. Hier lassen sich nun der Pfad sowie die Endung bestimmen oder ein Suffix und Präfix für die zuvor definierte Sprach-ID. Entwickler können zudem den Service anpassen, der den Aufruf tätigt. Das ist notwendig, wenn etwa ein eigener Wrapper-Service für HTTP existiert.
So wird bei Aufruf der Anwendung im Hintergrund ĂĽber die URL http://..../locale/de.json die deutsche Ăśbersetzung geladen:
import { Http } from '@angular/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
export function createTranslateLoader(http: Http) {
return new TranslateHttpLoader(http, './locale/', '.json');
}
@NgModule({
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
}
})
]
})
export class AppModule {}
Internationalisierung mit Direktiven und Pipes
Die Bibliothek ist nun einsatzbereit und die Dateien en.json und de.json als Datenquelle eingerichtet. Somit kann mit der Internationalisierung begonnen werden. Als Beispiel dient erneut das Ăśbersetzen der Tabelle des ersten Artikelteils beginnend mit dem Tabellenkopf.
Dazu definieren Entwickler die zuvor erwähnten Referenzen, die von der Direktive translate oder der gleichnamigen Pipe von ngx-translate benötigt werden, um eine Verbindung zur Übersetzungsdatei zu schaffen. An der Stelle zeigt sich der Unterschied zur Angular-Methode. Es wird kein Text zur Übersetzung markiert, sondern eine Funktion integriert, um selbst definierte Referenzen wie BOOKINGS.from beim Aufruf der Komponente zu ersetzen. Die Direktive translate nutzt dafür den Inhalt des HTML-Tag. Mit translateParams lassen sich zudem Parameter übergeben.
Als Alternative zur Direktive erzielt die Pipe translate den gleichen Effekt. Über die Expression benötigt man so jedoch keinen eigenen Tag. Damit Entwickler auch HTML nutzen können, ist es möglich, die Pipe an innerHTML zu übergeben. Attribute lassen sich auf die gleiche Weise übersetzen, wie BOOKINGS.bookingDate demonstriert:
<table>
<thead>
<tr>
<th translate>BOOKINGS.from</th>
<th translate [translateParams]="params">BOOKINGS.to</th>
<th>{{'BOOKINGS.passengers' | translate}}</th>
<th>{{'BOOKINGS.children' | translate:params}}</th>
<th [innerHTML]="'BOOKINGS.returnFlight' | translate"></th>
<th [title]="'BOOKINGS.bookingDate' | translate">#</th>
</tr>
</thead>
</table>
Die Datei de.json umfasst den Aufbau der Referenzen sowie deren Inhalt. Die Struktur können Entwickler selbst definieren. So auch die Verschachtelung in Untergruppen, die per Punktnotation im Template Verwendung findet. Im Beispiel trennt die Gruppe BOOKINGS die Tabelle klar ab. Das kann zur Übersichtlichkeit entscheidend beitragen:
{
"BOOKINGS": {
"from": "Von",
"to": "{{direction}} Nach",
"passengers": "Passagiere",
"children": "Davon Kinder ({{age}})",
"returnFlight": "<i>RĂĽckflug</i>",
"bookingDate": "Tag der Buchung"
}
}
Was noch fehlt, ist das Objekt params, das BOOKINGS.to und BOOKINGS.children verwendet. Es kommt aus der Komponente, die das gezeigte HTML nutzt, und enthält die Werte direction und age. So können Entwickler die Daten der Übersetzung als Expression anhängen und sie im Tabellenkopf anzeigen:
@Component({
templateUrl: './booking-details.component.html'
})
export class BookingDetailsComponent {
[...]
params = {
direction: '=>',
age: '<12'
};
}