ngx-translate:如何从多个目录加载翻译文件
Great question! The default TranslateHttpLoader only supports loading from a single directory, so we'll need to create a custom translation loader that fetches files from both assets/i18n/ and assets/data/, then merges their contents together. Here's how to implement this:
1. Create a Custom Multi-Path Translation Loader
First, we'll build a loader that implements ngx-translate's TranslateLoader interface. This loader will make parallel HTTP requests to both directories, then combine the results into one translation object.
import { HttpClient } from '@angular/common/http'; import { TranslateLoader } from '@ngx-translate/core'; import { Observable, forkJoin } from 'rxjs'; import { map } from 'rxjs/operators'; export class MultiTranslateHttpLoader implements TranslateLoader { constructor(private readonly http: HttpClient) {} getTranslation(lang: string): Observable<any> { // Fetch translation files from both directories const i18nFile$ = this.http.get(`./assets/i18n/${lang}.json`); const dataFile$ = this.http.get(`./assets/data/${lang}.json`); // Merge the two sets of translations (data translations override i18n if keys collide) return forkJoin([i18nFile$, dataFile$]).pipe( map(([i18nTranslations, dataTranslations]) => ({ ...i18nTranslations, ...dataTranslations })) ); } }
2. Update Your ngx-translate Configuration
Replace your existing loader factory with one that uses the custom loader we just created. Update your AppModule (or the module where you configure ngx-translate):
import { HttpClientModule, HttpClient } from '@angular/common/http'; import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; import { MultiTranslateHttpLoader } from './path-to-your-loader/multi-translate-http-loader'; // Factory function to provide the custom loader export function createTranslateLoader(http: HttpClient) { return new MultiTranslateHttpLoader(http); } @NgModule({ imports: [ HttpClientModule, TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: createTranslateLoader, deps: [HttpClient] } }) ], // ... other module metadata }) export class AppModule {}
3. Key Considerations
- Key Collisions: If your
i18n/anddata/files share identical translation keys, the data directory's values will override the i18n ones (because we spreaddataTranslationsafteri18nTranslationsin the merge). To avoid this, wrap your mock data translations in a namespace, e.g.:
Then access it in your templates like this:// assets/data/en.json { "mockData": { "userName": "Mock User", "productName": "Mock Product" } }{{ 'mockData.userName' | translate }} - Error Handling: For production, you might want to add error handling to the loader (e.g., catch HTTP errors if a file is missing and fall back to an empty object).
How It Works
The custom loader uses forkJoin to make parallel requests to both translation files. Once both requests complete, it merges the two JSON objects into one, which ngx-translate uses as its translation dictionary. This way, you can access translations from both directories using the standard TranslateService or translate pipe.
内容的提问来源于stack exchange,提问作者BlueCat

