在Typescript中 讀取 i18n 資料

Hi 大家好
最近在研究Angular 7中使用i18n
但不知道該如何在typescript中讀取i18n的資料

所以…在網路上爬文後做了一個奇怪的解法
目前是可以抓到資料, 但不知道會不會有效能上問題

程式碼如下

main.ts

...
import { I18nService } from 'app/services/i18n.service';
...

let locale = localStorage.getItem('locale') || 'en';
if( ['en', 'zh-Hant'].indexOf(locale) < 0 ) {
    localStorage.setItem('local', 'en');
    locale = 'en';
}

function getTranslationProviders( locale: string ): Promise<StaticProvider[]> {

    // Set HTML lang tag
    document.querySelector('html').setAttribute('lang', locale);

    // Get the locale id as arugment or from the global
    //
    const localeValue = locale || document[ 'locale' ] as string;


    // return no providers if fail to get translation file for locale
    //
    const noProviders: StaticProvider[] = [{ provide: I18nService, useValue: new I18nService('') }];

    // No locale or AU, doesn't require translation
    //
    if ( !localeValue || localeValue === 'en' ) {
        return Promise.resolve( noProviders );
    }

    try {
        let translations;
        const xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (this.readyState != 4) return;
        
            if (this.status == 200) {
                translations = this.responseText;
            }
        };
        xhr.open("GET", `/assets/i18n/messages.${ localeValue }.xlf`, false);
        xhr.send();
        
        return Promise.resolve( [
            { provide: TRANSLATIONS, useValue: translations },
            { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
            { provide: I18nService, useValue: new I18nService(translations) }
        ]);
    } catch ( error ) {
        console.error( error );
        return Promise.resolve( noProviders );
    }
}

getTranslationProviders( locale ).then( providers => {
    platformBrowserDynamic(providers)
        .bootstrapModule(AppModule)
        .then( moduleRef => AppInjector.setInjector(moduleRef.injector) );
});

i18n.service.ts

...

@Injectable()
export class I18nService {

    constructor(private xlf: string) {
        if( xlf ) {
            this.xliff = new Xliff().load(xlf, '');
        }
    }

    private readonly xliff: any;

    get(key: string, def: string = 'No Translation'): string {
        if( !this.xlf ) { return def; }
        const values = this.xliff.i18nNodesByMsgId[key];
        if( Array.isArray(values) && values.length ) {
            return this.xliff.i18nNodesByMsgId[key][0].value;
        } else {
            return def;
        }
    }

}

在typescript中使用

...
    constructor(private i18n: I18nService) {}

    const title = this.i18n.get('Nav.Dashboard', 'Dashboard');

目前有時會感覺到頓頓的, 但也不確定是不是因為這寫法而引起的.

感謝

我沒有嘗試過這樣的做法,通常 xlf 檔案不是會在建置時就完成對應語系的輸出了,
如果是動態的,我之前是使用 ngx-translate 這一個套件

僅在載入前下載要使用的 xlf 檔案來變換使用的語系
ngx-translate 也有在評估使用, 確實是比較好設定一些

不知道 大家比較推薦哪套呢

我後來有點開bundle後的檔案看過
這種做法確實是使用JIT 而非AOT

所以我將轉為研究使用ngx-translate
謝謝你的回覆