我正在开发一个 Angular (v13) 项目,该项目使用
ngx-translate/core
表示 i18n。配置了多种语言(当前有 15 种)。我发现以下非常奇怪行为(TranslateService 被注入为this.translateService
):
this.translateService.getLangs()
将返回一个包含 15 种语言代码的数组(如预期)。我可以记录这个值或者例如使用这些值配置下拉选择。[0]
(表示 undefined
)、.length
(返回 0)、for-in
或 for-of
。没有 ...
运算符来创建带有值的新数组或对象,没有 Object.assign([], langs)
,没有 Array.from()
- 它们只是返回空数组。更不用说.map()
、.forEach()
等等typeof
表示对象,Array.isArray()
表示真实。一些基本示例代码:
ngOnInit(): void {
console.log(
this.translateService.getLangs(),
this.translateService.getLangs().length,
this.translateService.getLangs()[0],
this.translateService.getLangs().includes('en'),
this.translateService.getLangs().includes('aa')
);
}
在控制台显示:
[] 0 undefined false false
如果我展开
[]
,它会显示 15 个代码(包括“en”)和 length: 15
。
ngx-translate
中的错误吗?感谢Amer的评论为我指明了正确的方向。
this.translateService.getLangs()
加载语言之前调用 this.translateService.addLangs()
。语言值是通过 HttpClient.get()
请求获取的,该请求返回 Observable
并在收到结果后调用 addLangs()
(请参阅 Observable.subscribe(...)
)。 (所以没有什么有趣的事情,只是错误的理解。)complete
返回的Observable
的HttpClient.get()
回调中对语言数组执行任何操作(或使用其他可用的同步机制之一)。这是原始代码中的一个错误,现已修复。[]
(然后可以扩展到整个数组)对我来说是一个困惑。当数组在记录时可用时,它会被记录为已扩展,例如[ "ar", "en", .... ]
。 (当我单击控制台中的扩展小部件时,该数组显然已同时加载,这使得它可以在扩展时显示。)我可以通过将其保存在稍后初始化的字段中来解决完全相同的问题。
protected availableLanguages: string[] = [];
constructor(protected translateService: TranslateService, protected dataService: DataService, protected userConfigurationService: UserConfigurationService<string>)
{
this.translateService.store.onLangChange.pipe(takeUntilDestroyed()).subscribe((_: LangChangeEvent): void => {
this.availableLanguages = this.translateService.store.langs;
this.availableLanguages.sort();
});
}
可以进行测试,例如在像这样的 jasmine 中,关键是重新创建组件,以便在覆盖事件发射器后再次调用构造函数:
it('should handle default language change', () =>
{
const eventEmitter: EventEmitter<LangChangeEvent> = new EventEmitter<LangChangeEvent>();
component['translateService'].store.onLangChange = eventEmitter;
component['translateService'].store.langs = ['de', 'en'];
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
expect(component['availableLanguages']).toEqual(arrayContaining([]));
eventEmitter.emit({
lang: 'de',
translations: {}
});
expect(component['availableLanguages']).toEqual(arrayContaining(['de', 'en']));
});