Differenzansicht 16c-i18n
im Vergleich zu 16-guards

← Zurück zur Ãœbersicht | Demo | Quelltext auf GitHub
angular.buildi18n.json ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+ "version": 1,
4
+ "newProjectRoot": "projects",
5
+ "projects": {
6
+ "book-monkey": {
7
+ "projectType": "application",
8
+ "schematics": {},
9
+ "root": "",
10
+ "sourceRoot": "src",
11
+ "prefix": "bm",
12
+ "architect": {
13
+ "build": {
14
+ "builder": "@angular-devkit/build-angular:browser",
15
+ "options": {
16
+ "outputPath": "dist/book-monkey",
17
+ "index": "src/index.html",
18
+ "main": "src/main.ts",
19
+ "polyfills": [
20
+ "zone.js"
21
+ ],
22
+ "tsConfig": "tsconfig.app.json",
23
+ "assets": [
24
+ {
25
+ "glob": "**/*",
26
+ "input": "public"
27
+ }
28
+ ],
29
+ "styles": [
30
+ "src/styles.css"
31
+ ],
32
+ "scripts": [],
33
+ "localize": true
34
+ },
35
+ "configurations": {
36
+ "production": {
37
+ "budgets": [
38
+ {
39
+ "type": "initial",
40
+ "maximumWarning": "500kB",
41
+ "maximumError": "1MB"
42
+ },
43
+ {
44
+ "type": "anyComponentStyle",
45
+ "maximumWarning": "4kB",
46
+ "maximumError": "8kB"
47
+ }
48
+ ],
49
+ "outputHashing": "all"
50
+ },
51
+ "development": {
52
+ "buildOptimizer": false,
53
+ "optimization": false,
54
+ "vendorChunk": true,
55
+ "extractLicenses": false,
56
+ "sourceMap": true,
57
+ "namedChunks": true,
58
+ "localize": ["en-US"]
59
+ },
60
+ "locale-de": {
61
+ "localize": ["de"]
62
+ }
63
+ },
64
+ "defaultConfiguration": "production"
65
+ },
66
+ "serve": {
67
+ "builder": "@angular-devkit/build-angular:dev-server",
68
+ "configurations": {
69
+ "production": {
70
+ "buildTarget": "book-monkey:build:production"
71
+ },
72
+ "development": {
73
+ "buildTarget": "book-monkey:build:development"
74
+ },
75
+ "development-de": {
76
+ "buildTarget": "book-monkey:build:development,locale-de"
77
+ }
78
+ },
79
+ "defaultConfiguration": "development"
80
+ },
81
+ "extract-i18n": {
82
+ "builder": "@angular-devkit/build-angular:extract-i18n"
83
+ },
84
+ "test": {
85
+ "builder": "@angular-devkit/build-angular:karma",
86
+ "options": {
87
+ "polyfills": [
88
+ "zone.js",
89
+ "zone.js/testing"
90
+ ],
91
+ "tsConfig": "tsconfig.spec.json",
92
+ "assets": [
93
+ {
94
+ "glob": "**/*",
95
+ "input": "public"
96
+ }
97
+ ],
98
+ "styles": [
99
+ "src/styles.css"
100
+ ],
101
+ "scripts": []
102
+ }
103
+ },
104
+ "lint": {
105
+ "builder": "@angular-eslint/builder:lint",
106
+ "options": {
107
+ "lintFilePatterns": [
108
+ "src/**/*.ts",
109
+ "src/**/*.html"
110
+ ]
111
+ }
112
+ }
113
+ },
114
+ "i18n": {
115
+ "sourceLocale": "en-US",
116
+ "locales": {
117
+ "de": {
118
+ "translation": "messages.de.xlf"
119
+ }
120
+ }
121
+ }
122
+ }
123
+ },
124
+ "cli": {
125
+ "schematicCollections": [
126
+ "angular-eslint"
127
+ ]
128
+ }
129
+ }
angular.json CHANGED
@@ -27,7 +27,8 @@
27
  "index": "src/index.html",
28
  "browser": "src/main.ts",
29
  "polyfills": [
30
- "zone.js"
 
31
  ],
32
  "tsConfig": "tsconfig.app.json",
33
  "assets": [
@@ -85,7 +86,8 @@
85
  "options": {
86
  "polyfills": [
87
  "zone.js",
88
- "zone.js/testing"
 
89
  ],
90
  "tsConfig": "tsconfig.spec.json",
91
  "assets": [
27
  "index": "src/index.html",
28
  "browser": "src/main.ts",
29
  "polyfills": [
30
+ "zone.js",
31
+ "@angular/localize/init"
32
  ],
33
  "tsConfig": "tsconfig.app.json",
34
  "assets": [
86
  "options": {
87
  "polyfills": [
88
  "zone.js",
89
+ "zone.js/testing",
90
+ "@angular/localize/init"
91
  ],
92
  "tsConfig": "tsconfig.spec.json",
93
  "assets": [
package.json CHANGED
@@ -30,6 +30,7 @@
30
  "@angular-devkit/build-angular": "^19.1.1",
31
  "@angular/cli": "^19.1.1",
32
  "@angular/compiler-cli": "^19.1.0",
 
33
  "@types/jasmine": "~5.1.0",
34
  "angular-eslint": "19.0.2",
35
  "eslint": "^9.16.0",
30
  "@angular-devkit/build-angular": "^19.1.1",
31
  "@angular/cli": "^19.1.1",
32
  "@angular/compiler-cli": "^19.1.0",
33
+ "@angular/localize": "^19.1.1",
34
  "@types/jasmine": "~5.1.0",
35
  "angular-eslint": "19.0.2",
36
  "eslint": "^9.16.0",
public/messages.de.json ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "locale": "de",
3
+ "translations": {
4
+ "BookCreateComponentTitle": "Buch anlegen",
5
+ "BookEditComponentTitle": "Buch bearbeiten",
6
+ "BookFormComponentLabelTitle": "Titel",
7
+ "BookFormComponentLabelSubtitle": "Untertitel",
8
+ "BookFormComponentLabelIsbn": "ISBN",
9
+ "BookFormComponentLabelAuthors": "Autorinnen/Autoren",
10
+ "BookFormComponentAddAuthor": " + Autorin/Autor ",
11
+ "BookFormComponentLabelDescription": "Beschreibung",
12
+ "BookFormComponentLabelPublished": "Veröffentlicht",
13
+ "BookFormComponentLabelThumbnail": "Vorschaubild URL",
14
+ "BookFormComponentSave": " Speichern ",
15
+ "BookFormComponentErrorTitleRequired": "Ein Titel muss angegeben werden.",
16
+ "BookFormComponentErrorIsbnRequired": "Eine ISBN muss angegeben werden.",
17
+ "BookFormComponentErrorIsbnFormat": "Die ISBN muss aus 10 oder 13 Zahlen bestehen.",
18
+ "BookFormComponentErrorIsbnExists": "DIe ISBN existiert bereits.",
19
+ "BookFormComponentErrorAtLeastOneAuthor": "Es muss mindestens ein Name angegeben werden.",
20
+ "AppComponentHome": "Startseite",
21
+ "AppComponentBooks": "Bücher",
22
+ "AppComponentAdmin": "Administration",
23
+ "AppComponentLogin": "Anmelden",
24
+ "AppComponentLogout": "Abmelden",
25
+ "BookDetailsComponentAuthors": "Autorinnen/Autoren",
26
+ "BookDetailsComponentIsbn": "ISBN",
27
+ "BookDetailsComponentPublished": "Veröffentlicht",
28
+ "BookDetailsComponentDescription": "Beschreibung",
29
+ "BookDetailsComponentAltCover": "Buchcover",
30
+ "BookDetailsComponentBackToList": "Zurück zur Liste",
31
+ "BookDetailsComponentRemove": " Buch entfernen ",
32
+ "BookDetailsComponentEdit": " Buch bearbeiten ",
33
+ "BookListItemComponentAltCover": "Buchcover",
34
+ "BookListItemComponentIsbn": "ISBN",
35
+ "BookListComponentTitle": "Bücher",
36
+ "BookListComponentNoBooks": " Keine Bücher verfügbar. ",
37
+ "HomeComponentTitle": "Startseite",
38
+ "HomeComponentBooks": " Zur Buchliste\n",
39
+ "HomeComponentSearchHeadline": "Suche",
40
+ "SearchComponentInput": "Suche",
41
+ "AuthGuardAlert": "Nicht angemeldet!"
42
+ }
43
+ }
src/app/admin/book-create/book-create.component.html CHANGED
@@ -1,3 +1,3 @@
1
- <h1>Create Book</h1>
2
 
3
  <bm-book-form (submitBook)="create($event)"></bm-book-form>
1
+ <h1 i18n="title create book|Title for the create book page@@BookCreateComponentTitle">Create Book</h1>
2
 
3
  <bm-book-form (submitBook)="create($event)"></bm-book-form>
src/app/admin/book-edit/book-edit.component.html CHANGED
@@ -1,4 +1,4 @@
1
- <h1>Edit Book</h1>
2
 
3
  <bm-book-form
4
  *ngIf="book$ | async as book"
1
+ <h1 i18n="title edit book|Title for the edit book page@@BookEditComponentTitle">Edit Book</h1>
2
 
3
  <bm-book-form
4
  *ngIf="book$ | async as book"
src/app/admin/book-form/book-form.component.html CHANGED
@@ -1,28 +1,25 @@
1
  <form [formGroup]="form" (ngSubmit)="submitForm()">
2
- <label for="title">Title</label>
3
  <input id="title" formControlName="title">
4
  <bm-form-errors
5
  controlName="title"
6
- [messages]="{ required: 'Title is required' }">
7
  </bm-form-errors>
8
 
9
- <label for="subtitle">Subtitle</label>
10
  <input id="subtitle" formControlName="subtitle">
11
 
12
- <label for="isbn">ISBN</label>
13
  <input id="isbn" formControlName="isbn">
14
  <bm-form-errors
15
  controlName="isbn"
16
- [messages]="{
17
- required: 'ISBN is required',
18
- isbnformat: 'ISBN must have 10 or 13 chars',
19
- isbnexists: 'ISBN already exists'
20
- }">
21
  </bm-form-errors>
22
 
23
- <label>Authors</label>
24
  <button type="button" class="add"
25
- (click)="addAuthorControl()">
 
26
  + Author
27
  </button>
28
  <fieldset formArrayName="authors">
@@ -33,19 +30,19 @@
33
  </fieldset>
34
  <bm-form-errors
35
  controlName="authors"
36
- [messages]="{ atleastonevalue: 'At least one author required' }">
37
  </bm-form-errors>
38
 
39
- <label for="description">Description</label>
40
  <textarea id="description" formControlName="description"></textarea>
41
 
42
- <label for="published">Published</label>
43
  <input type="date" useValueAsLocalIso id="published" formControlName="published">
44
 
45
- <label for="thumbnailUrl">Thumbnail URL</label>
46
  <input type="url" id="thumbnailUrl" formControlName="thumbnailUrl">
47
 
48
- <button type="submit" [disabled]="form.invalid">
49
  Save
50
  </button>
51
  </form>
1
  <form [formGroup]="form" (ngSubmit)="submitForm()">
2
+ <label for="title" i18n="label title|Label for the title input@@BookFormComponentLabelTitle">Title</label>
3
  <input id="title" formControlName="title">
4
  <bm-form-errors
5
  controlName="title"
6
+ [messages]="errorsTranslated('title')">
7
  </bm-form-errors>
8
 
9
+ <label for="subtitle" i18n="label subtitle|Label for the subtitle input@@BookFormComponentLabelSubtitle">Subtitle</label>
10
  <input id="subtitle" formControlName="subtitle">
11
 
12
+ <label for="isbn" i18n="label isbn|Label for the ISBN input@@BookFormComponentLabelIsbn">ISBN</label>
13
  <input id="isbn" formControlName="isbn">
14
  <bm-form-errors
15
  controlName="isbn"
16
+ [messages]="errorsTranslated('isbn')">
 
 
 
 
17
  </bm-form-errors>
18
 
19
+ <label i18n="label authors|Label for the authors inputs@@BookFormComponentLabelAuthors">Authors</label>
20
  <button type="button" class="add"
21
+ (click)="addAuthorControl()"
22
+ i18n="button add author|Text for the button to add an author input@@BookFormComponentAddAuthor">
23
  + Author
24
  </button>
25
  <fieldset formArrayName="authors">
30
  </fieldset>
31
  <bm-form-errors
32
  controlName="authors"
33
+ [messages]="errorsTranslated('authors')">
34
  </bm-form-errors>
35
 
36
+ <label for="description" i18n="label description|Label for the description text@@BookFormComponentLabelDescription">Description</label>
37
  <textarea id="description" formControlName="description"></textarea>
38
 
39
+ <label for="published" i18n="label published|Label for the published input@@BookFormComponentLabelPublished">Published</label>
40
  <input type="date" useValueAsLocalIso id="published" formControlName="published">
41
 
42
+ <label for="thumbnailUrl" i18n="label thumbnail|Label for the thumbnail input@@BookFormComponentLabelThumbnail">Thumbnail URL</label>
43
  <input type="url" id="thumbnailUrl" formControlName="thumbnailUrl">
44
 
45
+ <button type="submit" [disabled]="form.invalid" i18n="button save|Text for save button@@BookFormComponentSave">
46
  Save
47
  </button>
48
  </form>
src/app/admin/book-form/book-form.component.ts CHANGED
@@ -89,4 +89,21 @@ export class BookFormComponent implements OnChanges {
89
 
90
  this.submitBook.emit(newBook);
91
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
89
 
90
  this.submitBook.emit(newBook);
91
  }
92
+
93
+ errorsTranslated(controlName: string) {
94
+ const errorTexts: { [controlName: string]: { [errorCode: string]: string }} = {
95
+ title: {
96
+ required: $localize`:title required error@@BookFormComponentErrorTitleRequired:Title is required`
97
+ },
98
+ isbn: {
99
+ required: $localize`:isbn required error@@BookFormComponentErrorIsbnRequired:ISBN is required`,
100
+ isbnformat: $localize`:isbn format error@@BookFormComponentErrorIsbnFormat:ISBN must have 10 or 13 characters`,
101
+ isbnexists: $localize`:isbn exists error@@BookFormComponentErrorIsbnExists:ISBN already exists`,
102
+ },
103
+ authors: {
104
+ atleastonevalue: $localize`:at least one author error@@BookFormComponentErrorAtLeastOneAuthor:At least one author required`
105
+ }
106
+ }
107
+ return errorTexts[controlName] || {};
108
+ }
109
  }
src/app/app.component.html CHANGED
@@ -1,14 +1,18 @@
1
  <nav>
2
- <a routerLink="/home" routerLinkActive="active" ariaCurrentWhenActive="page">Home</a>
3
- <a routerLink="/books" routerLinkActive="active" ariaCurrentWhenActive="page">Books</a>
4
- <a routerLink="/admin" routerLinkActive="active" ariaCurrentWhenActive="page">Administration</a>
5
  <div class="actions">
6
  <button class="green"
7
  (click)="auth.login()"
8
- *ngIf="!auth.isAuthenticated">Login</button>
 
9
  <button class="red"
10
  (click)="auth.logout()"
11
- *ngIf="auth.isAuthenticated">Logout</button>
 
 
 
12
  </div>
13
  </nav>
14
 
1
  <nav>
2
+ <a routerLink="/home" routerLinkActive="active" ariaCurrentWhenActive="page" i18n="nav home@@AppComponentHome">Home</a>
3
+ <a routerLink="/books" routerLinkActive="active" ariaCurrentWhenActive="page" i18n="nav books@@AppComponentBooks">Books</a>
4
+ <a routerLink="/admin" routerLinkActive="active" ariaCurrentWhenActive="page" i18n="nav admin@@AppComponentAdmin">Administration</a>
5
  <div class="actions">
6
  <button class="green"
7
  (click)="auth.login()"
8
+ *ngIf="!auth.isAuthenticated"
9
+ i18n="login@@AppComponentLogin">Login</button>
10
  <button class="red"
11
  (click)="auth.logout()"
12
+ *ngIf="auth.isAuthenticated"
13
+ i18n="logout@@AppComponentLogout">Logout</button>
14
+ <button (click)="changeLocale('de')">DE</button>
15
+ <button (click)="changeLocale('en')">EN</button>
16
  </div>
17
  </nav>
18
 
src/app/app.component.ts CHANGED
@@ -10,4 +10,9 @@ import { AuthService } from './shared/auth.service';
10
  })
11
  export class AppComponent {
12
  constructor(public auth: AuthService) {}
 
 
 
 
 
13
  }
10
  })
11
  export class AppComponent {
12
  constructor(public auth: AuthService) {}
13
+
14
+ changeLocale(targetLang: string) {
15
+ localStorage.setItem('locale', targetLang);
16
+ location.reload();
17
+ }
18
  }
src/app/books/book-details/book-details.component.html CHANGED
@@ -3,32 +3,34 @@
3
  <p role="doc-subtitle" *ngIf="book.subtitle">{{ book.subtitle }}</p>
4
  <div class="header">
5
  <div>
6
- <h2>Authors</h2>
7
  <ul>
8
  <li *ngFor="let author of book.authors">{{ author }}</li>
9
  </ul>
10
  </div>
11
  <div>
12
- <h2>ISBN</h2>
13
  {{ book.isbn | isbn }}
14
  </div>
15
  <div *ngIf="book.published">
16
- <h2>Published</h2>
17
  {{ book.published | date:'longDate' }}
18
  </div>
19
  </div>
20
- <h2>Description</h2>
21
  <p>{{ book.description }}</p>
22
  <img *ngIf="book.thumbnailUrl"
23
  [src]="book.thumbnailUrl"
24
- alt="Cover">
25
- <a class="button arrow-left" routerLink="..">Back to list</a>
 
26
  <ng-container *bmLoggedinOnly>
27
- <button class="red" bmConfirm="Remove book?" (confirm)="removeBook(book.isbn)">
28
  Remove book
29
  </button>
30
  <a class="button"
31
- [routerLink]="['/admin/edit', book.isbn]">
 
32
  Edit book
33
  </a>
34
  </ng-container>
3
  <p role="doc-subtitle" *ngIf="book.subtitle">{{ book.subtitle }}</p>
4
  <div class="header">
5
  <div>
6
+ <h2 i18n="headline authors|Headline for the authors@@BookDetailsComponentAuthors">Authors</h2>
7
  <ul>
8
  <li *ngFor="let author of book.authors">{{ author }}</li>
9
  </ul>
10
  </div>
11
  <div>
12
+ <h2 i18n="headline ISBN|Headline for the ISBN@@BookDetailsComponentIsbn">ISBN</h2>
13
  {{ book.isbn | isbn }}
14
  </div>
15
  <div *ngIf="book.published">
16
+ <h2 i18n="headline published|Headline for the published date@@BookDetailsComponentPublished">Published</h2>
17
  {{ book.published | date:'longDate' }}
18
  </div>
19
  </div>
20
+ <h2 i18n="headline description|Headline for the description@@BookDetailsComponentDescription">Description</h2>
21
  <p>{{ book.description }}</p>
22
  <img *ngIf="book.thumbnailUrl"
23
  [src]="book.thumbnailUrl"
24
+ alt="Cover"
25
+ i18n-alt="cover alt text|Alternative text when no cover is defined@@BookDetailsComponentAltCover">
26
+ <a class="button arrow-left" routerLink=".." i18n="link back|Link for navigating back to the books list@@BookDetailsComponentBackToList">Back to list</a>
27
  <ng-container *bmLoggedinOnly>
28
+ <button class="red" bmConfirm="Remove book?" (confirm)="removeBook(book.isbn)" i18n="button remove|Button text to remove a book@@BookDetailsComponentRemove">
29
  Remove book
30
  </button>
31
  <a class="button"
32
+ [routerLink]="['/admin/edit', book.isbn]"
33
+ i18n="button edit|Button text to edit a book@@BookDetailsComponentEdit">
34
  Edit book
35
  </a>
36
  </ng-container>
src/app/books/book-list/book-list.component.html CHANGED
@@ -1,9 +1,9 @@
1
- <h1>Books</h1>
2
  <ul class="book-list" *ngIf="books$ | async as books">
3
  <li *ngFor="let book of books">
4
  <bm-book-list-item [book]="book"></bm-book-list-item>
5
  </li>
6
- <li *ngIf="!books.length">
7
  No books available.
8
  </li>
9
  </ul>
1
+ <h1 i18n="title books|Title for the books page@@BookListComponentTitle">Books</h1>
2
  <ul class="book-list" *ngIf="books$ | async as books">
3
  <li *ngFor="let book of books">
4
  <bm-book-list-item [book]="book"></bm-book-list-item>
5
  </li>
6
+ <li *ngIf="!books.length" i18n="text no books|Text displayed when no books are available@@BookListComponentNoBooks">
7
  No books available.
8
  </li>
9
  </ul>
src/app/books/book-list-item/book-list-item.component.html CHANGED
@@ -1,5 +1,5 @@
1
  <a *ngIf="book" [routerLink]="book.isbn" class="list-item">
2
- <img *ngIf="book.thumbnailUrl" [src]="book.thumbnailUrl" alt="Cover">
3
  <h2>{{ book.title }}</h2>
4
  <p role="doc-subtitle" *ngIf="book.subtitle">
5
  {{ book.subtitle }}
@@ -9,5 +9,5 @@
9
  {{ author }}
10
  </li>
11
  </ul>
12
- <div>ISBN {{ book.isbn | isbn }}</div>
13
  </a>
1
  <a *ngIf="book" [routerLink]="book.isbn" class="list-item">
2
+ <img *ngIf="book.thumbnailUrl" [src]="book.thumbnailUrl" alt="Cover" i18n-alt="cover alt text|Alternative text when no cover is defined@@BookListItemComponentAltCover">
3
  <h2>{{ book.title }}</h2>
4
  <p role="doc-subtitle" *ngIf="book.subtitle">
5
  {{ book.subtitle }}
9
  {{ author }}
10
  </li>
11
  </ul>
12
+ <div><ng-container i18n="book text before ISBN|Text for ISBN right before the number@@BookListItemComponentIsbn">ISBN</ng-container> {{ book.isbn | isbn }}</div>
13
  </a>
src/app/home/home.component.html CHANGED
@@ -1,8 +1,8 @@
1
- <h1>Home</h1>
2
 
3
- <a routerLink="/books" class="button red">
4
  Show book list
5
  </a>
6
 
7
- <h2>Search</h2>
8
  <bm-search></bm-search>
1
+ <h1 i18n="title home|Title for the home page@@HomeComponentTitle">Home</h1>
2
 
3
+ <a routerLink="/books" class="button red" i18n="link books list|Text of the link to the books screen@@HomeComponentBooks">
4
  Show book list
5
  </a>
6
 
7
+ <h2 i18n="headline search|Headline text above the search input@@HomeComponentSearchHeadline">Search</h2>
8
  <bm-search></bm-search>
src/app/search/search.component.html CHANGED
@@ -1,6 +1,7 @@
1
  <input type="search"
2
  autocomplete="off"
3
  aria-label="Search"
 
4
  [class.loading]="isLoading"
5
  #searchInput
6
  (input)="input$.next(searchInput.value)">
1
  <input type="search"
2
  autocomplete="off"
3
  aria-label="Search"
4
+ i18n-aria-label="search input ARIA label|input search@@SearchComponentInput"
5
  [class.loading]="isLoading"
6
  #searchInput
7
  (input)="input$.next(searchInput.value)">
src/main.ts CHANGED
@@ -1,7 +1,30 @@
 
 
 
 
 
1
  import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 
 
2
  import { AppModule } from './app/app.module';
3
 
4
- platformBrowserDynamic().bootstrapModule(AppModule, {
5
- ngZoneEventCoalescing: true,
6
- })
7
- .catch(err => console.error(err));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /// <reference types="@angular/localize" />
2
+
3
+ import { registerLocaleData } from '@angular/common';
4
+ import { LOCALE_ID } from '@angular/core';
5
+ import { loadTranslations } from '@angular/localize';
6
  import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
7
+ import localeDe from '@angular/common/locales/de';
8
+
9
  import { AppModule } from './app/app.module';
10
 
11
+ async function setupLocale() {
12
+ if (localStorage.getItem('locale') !== 'de') {
13
+ return 'en-US';
14
+ }
15
+ const response = await fetch('messages.de.json');
16
+ const result = await response.json();
17
+ loadTranslations(result.translations);
18
+ registerLocaleData(localeDe);
19
+ return 'de';
20
+ }
21
+
22
+ setupLocale().then(localeValue => {
23
+ platformBrowserDynamic([
24
+ { provide: LOCALE_ID, useValue: localeValue }
25
+ ])
26
+ .bootstrapModule(AppModule, {
27
+ ngZoneEventCoalescing: true
28
+ })
29
+ .catch(err => console.error(err));
30
+ });
tsconfig.app.json CHANGED
@@ -4,7 +4,9 @@
4
  "extends": "./tsconfig.json",
5
  "compilerOptions": {
6
  "outDir": "./out-tsc/app",
7
- "types": []
 
 
8
  },
9
  "files": [
10
  "src/main.ts"
4
  "extends": "./tsconfig.json",
5
  "compilerOptions": {
6
  "outDir": "./out-tsc/app",
7
+ "types": [
8
+ "@angular/localize"
9
+ ]
10
  },
11
  "files": [
12
  "src/main.ts"
tsconfig.spec.json CHANGED
@@ -5,7 +5,8 @@
5
  "compilerOptions": {
6
  "outDir": "./out-tsc/spec",
7
  "types": [
8
- "jasmine"
 
9
  ]
10
  },
11
  "include": [
5
  "compilerOptions": {
6
  "outDir": "./out-tsc/spec",
7
  "types": [
8
+ "jasmine",
9
+ "@angular/localize"
10
  ]
11
  },
12
  "include": [