Angular 14中ngInit调用异步方法失效问题求助
Angular 14中ngOnInit内调用异步方法失效的解决方法
先优化你的异步方法
你当前代码里await和.then()混用属于冗余写法,直接用await获取Promise结果即可,优化后代码更简洁:
async setInterfaceDatatableHeaders() { const bankName = await GetTranslatedValue(this.translate, "SUPPLIERMANAGEMENT.Bank"); const accountOwnerName = await GetTranslatedValue(this.translate, "GENERAL.AccountOwnerName"); const interfaceBankID = await GetTranslatedValue(this.translate, "SUPPLIERMANAGEMENT.InterfaceBankID"); const accountOwnerTel = await GetTranslatedValue(this.translate, "GENERAL.AccountOwnerTel"); this.interfaceDatatableHeaders = [ new DataTableHeaderDTO('BankName', bankName, 'text'), new DataTableHeaderDTO('AccountOwnerName', accountOwnerName, 'text'), new DataTableHeaderDTO('InterfaceBankID', interfaceBankID, 'text'), new DataTableHeaderDTO('AccountOwnerTel', accountOwnerTel, 'text'), ]; }
核心问题与解决方案
你遇到的问题本质是ngOnInit执行时,TranslateService的翻译资源尚未加载完成,导致GetTranslatedValue无法正确返回结果;而setTimeout能生效是因为它把代码推到下一个宏任务队列执行,此时翻译资源可能已经加载完毕。以下是无需setTimeout的解决办法:
方案1:等待翻译资源加载完成后执行
通过TranslateService的getTranslation方法确保当前语言的翻译资源加载完成,再调用你的异步方法:
// 方式1:使用subscribe ngOnInit(): void { this.translate.getTranslation(this.translate.currentLang).subscribe(() => { this.setInterfaceDatatableHeaders(); }); } // 方式2:结合async/await async ngOnInit(): Promise<void> { await this.translate.getTranslation(this.translate.currentLang).toPromise(); await this.setInterfaceDatatableHeaders(); }
方案2:手动触发变更检测(针对OnPush策略组件)
如果你的组件使用了ChangeDetectionStrategy.OnPush,异步更新数据后Angular可能不会自动触发变更检测,此时可以注入ChangeDetectorRef手动触发:
- 先在组件构造函数注入依赖:
constructor(private translate: TranslateService, private cdr: ChangeDetectorRef) {}
- 修改
setInterfaceDatatableHeaders方法:
async setInterfaceDatatableHeaders() { // ... 优化后的获取翻译代码 this.interfaceDatatableHeaders = [/* ... */]; this.cdr.detectChanges(); // 手动触发变更检测 }
- 在ngOnInit中直接调用:
async ngOnInit(): Promise<void> { await this.setInterfaceDatatableHeaders(); }
方案3:并行请求优化(可选)
你的四个翻译请求是串行执行的,可以改成并行请求提升性能:
async setInterfaceDatatableHeaders() { const [bankName, accountOwnerName, interfaceBankID, accountOwnerTel] = await Promise.all([ GetTranslatedValue(this.translate, "SUPPLIERMANAGEMENT.Bank"), GetTranslatedValue(this.translate, "GENERAL.AccountOwnerName"), GetTranslatedValue(this.translate, "SUPPLIERMANAGEMENT.InterfaceBankID"), GetTranslatedValue(this.translate, "GENERAL.AccountOwnerTel") ]); this.interfaceDatatableHeaders = [ new DataTableHeaderDTO('BankName', bankName, 'text'), new DataTableHeaderDTO('AccountOwnerName', accountOwnerName, 'text'), new DataTableHeaderDTO('InterfaceBankID', interfaceBankID, 'text'), new DataTableHeaderDTO('AccountOwnerTel', accountOwnerTel, 'text'), ]; this.cdr?.detectChanges(); }
内容的提问来源于stack exchange,提问作者farshad fahimi
相关产品推荐
相关产品推荐

