使用字符串设置ngx-translate默认语言失效问题排查
问题
我正在开发一款具备翻译功能的应用,计划将英语设为默认语言,采用ngx-translate实现翻译功能,在构造函数中声明了translateService变量。
构造函数代码:
constructor(private translateService: TranslateService, private platform: Platform, private globalization: Globalization, private storage: Storage)
我将defaultLang变量赋值为代表英语的字符串'en',并传递给translateService.setDefaultLang(defaultLang)设置默认语言,但英语仍未成为默认语言,请问这是什么原因?
initialize方法代码:
async initialize() { if (this.isInitialized) { return Promise.resolve(); } if (this.initializeListeners.length > 0) { // a parallel call has already been started return new Promise(success => { this.initializeListeners.push(success); }); } return new Promise(async success => { let defaultLang = 'en'; this.translateService.setDefaultLang(defaultLang); this.initializeListeners.push(success); await this.platform.ready(); let lang = await this.storage.get(LanguageService.STORAGE_KEY); if (!lang && checkAvailability(Globalization.getPluginRef(), null, Globalization.getPluginName()) === true) { // no previous language found -> get device language try { let preferredLanguage = await this.globalization.getPreferredLanguage(); if (preferredLanguage && preferredLanguage.value) { lang = preferredLanguage.value; if (lang.indexOf('-') > -1) { lang = lang.split('-')[0]; } if (lang.indexOf('_') > -1) { lang = lang.split('_')[0]; } lang = lang.toLowerCase(); if (this.availableLanguages.indexOf(lang) == -1) { // detected language is not available lang = null; } } } catch (e) { } } if (!lang) { lang = defaultLang; } this.textDirection = this.rtlLanguages.indexOf(lang) >= 0 ? 'rtl' : 'ltr'; this.platform.setDir(this.rtlLanguages.indexOf(lang) >= 0 ? 'rtl' : 'ltr', true); await this.translateService.use(lang); setTimeout(() => { // use timeout to let language switch propagate this.isInitialized = true; this.initializeListeners.map(success => { success(); }); this.initializeListeners = null; }, 100); }); }
我原本以为只需声明变量并传入对应字符串即可生效。
问题原因与解决方案
核心原因
你调用的translateService.setDefaultLang('en')是设置翻译资源缺失时的回退语言,并非直接设置当前应用显示的语言。真正决定当前显示语言的是后续的translateService.use(lang)逻辑:
- 如果本地存储有之前保存的语言,直接使用该语言
- 如果存储无值,会尝试获取设备系统语言,只要系统语言在
availableLanguages列表中,就会用该语言 - 只有上述两种情况都不满足时,才会回退到
defaultLang的值
修复方案
如果要强制让英语成为默认启动语言,可按以下方式调整逻辑:
调整语言优先级,优先使用默认语言
修改initialize方法,将defaultLang作为lang的初始值,再根据存储或系统语言选择性覆盖:async initialize() { if (this.isInitialized) { return Promise.resolve(); } if (this.initializeListeners.length > 0) { return new Promise(success => { this.initializeListeners.push(success); }); } return new Promise(async success => { let defaultLang = 'en'; this.translateService.setDefaultLang(defaultLang); this.initializeListeners.push(success); await this.platform.ready(); // 先将lang设为默认英语 let lang = defaultLang; // 读取本地存储的用户偏好语言,存在则替换 let storedLang = await this.storage.get(LanguageService.STORAGE_KEY); if (storedLang) { lang = storedLang; } else if (checkAvailability(Globalization.getPluginRef(), null, Globalization.getPluginName()) === true) { try { let preferredLanguage = await this.globalization.getPreferredLanguage(); if (preferredLanguage && preferredLanguage.value) { let systemLang = preferredLanguage.value; if (systemLang.indexOf('-') > -1) { systemLang = systemLang.split('-')[0]; } if (systemLang.indexOf('_') > -1) { systemLang = systemLang.split('_')[0]; } systemLang = systemLang.toLowerCase(); // 仅当系统语言在可用列表中时,才替换默认语言 if (this.availableLanguages.indexOf(systemLang) !== -1) { lang = systemLang; } } } catch (e) { } } this.textDirection = this.rtlLanguages.indexOf(lang) >= 0 ? 'rtl' : 'ltr'; this.platform.setDir(this.rtlLanguages.indexOf(lang) >= 0 ? 'rtl' : 'ltr', true); await this.translateService.use(lang); setTimeout(() => { this.isInitialized = true; this.initializeListeners.map(success => { success(); }); this.initializeListeners = null; }, 100); }); }确认
availableLanguages包含英语
检查this.availableLanguages数组中是否存在'en',如果没有,即使设置了默认语言,也无法加载英语翻译资源,自然无法显示英语。明确两个API的差异
setDefaultLang(lang):仅在当前语言无对应翻译时生效,作为兜底选项use(lang):直接设置当前应用显示的语言,优先级高于默认语言
内容的提问来源于stack exchange,提问作者nzl81372
相关产品推荐
相关产品推荐

