如何在Fiori多Tile项目中加载共享i18n文件?
解决Fiori应用manifest中sap.app元数据i18n绑定失效的问题
这个问题我之前在项目里也碰到过,核心原因是:manifest.json里的sap.app部分属于应用的静态元数据,SAPUI5框架会在Component初始化之前就读取并解析这部分内容,所以你在Component.js里注册的公共i18n模型,根本赶不上这一步的绑定解析,自然会显示占位符。
下面给你几个可行的解决方案,按推荐程度排序:
方案1:直接在manifest中配置公共i18n资源(最推荐)
UI5支持在manifest的i18n节点中配置多个资源文件,框架会自动合并这些文件的内容。这样manifest里的sap.app元数据就能直接读取到公共i18n的内容,不需要额外代码处理。
配置步骤:
- 在
/analytic/webapp/manifest.json的sap.app节点下,修改i18n配置,添加公共i18n文件的路径:
"sap.app": { "id": "your.app.id.analytics", "i18n": [ { "uri": "../../common/i18n/i18n.properties", // 指向公共i18n文件,路径根据实际结构调整 "type": "properties" }, { "uri": "i18n/i18n.properties", // 保留本地i18n(如果有) "type": "properties" } ], "title": "{{i18n>common.analyticsTitle}}", // 公共i18n中的键,建议加前缀避免冲突 "description": "{{i18n>common.analyticsDesc}}" }
- 在公共i18n文件(
/common/i18n/i18n.properties)中添加对应的键值对:
common.analyticsTitle=Analytics Dashboard common.analyticsDesc=View real-time business analytics data
这个方案完全符合UI5的设计逻辑,兼容性最好,不需要修改Component.js的代码,是最优解。
方案2:通过Component动态更新元数据
如果因为某些原因不能修改manifest的i18n配置,可以通过覆盖Component的方法,在初始化完成后动态更新sap.app的title和description。
代码示例:
sap.ui.define([ "sap/ui/core/UIComponent", "../common/util/Utils" ], function(UIComponent, Utils) { "use strict"; return UIComponent.extend("analytics.Component", { metadata: { manifest: "json" }, init: function() { // 先执行父类的init方法 UIComponent.prototype.init.apply(this, arguments); // 你的现有代码:注册模块路径、加载公共i18n模型 Utils.setCommonResource(this); // 获取公共i18n模型(假设你设置的模型名称是"i18n",如果是其他名称请替换) const oCommonI18nModel = this.getModel("i18n"); if (oCommonI18nModel) { // 获取Component的元数据对象 const oMetadata = this.getMetadata(); // 更新title和description oMetadata.setTitle(oCommonI18nModel.getText("common.analyticsTitle")); oMetadata.setDescription(oCommonI18nModel.getText("common.analyticsDesc")); // 触发titleChanged事件,通知Fiori Shell更新Tile显示 this.fireEvent("titleChanged", { title: oMetadata.getTitle(), description: oMetadata.getDescription() }); } }, // 可选:覆盖getMetadata方法,确保每次获取元数据都是最新的 getMetadata: function() { const oMetadata = UIComponent.prototype.getMetadata.apply(this, arguments); const oCommonI18nModel = this.getModel("i18n"); if (oCommonI18nModel) { oMetadata.setTitle(oCommonI18nModel.getText("common.analyticsTitle")); oMetadata.setDescription(oCommonI18nModel.getText("common.analyticsDesc")); } return oMetadata; } }); });
这个方法需要注意:如果你的公共i18n模型名称不是"i18n",要替换成实际的模型名称(比如"commonI18n")。
方案3:通过Fiori Launchpad API更新Tile显示(仅适用于FLP环境)
如果你的应用只在Fiori Launchpad中运行,可以直接调用FLP的服务来更新对应Tile的显示文本。
代码示例:
sap.ui.define([ "sap/ui/core/UIComponent", "../common/util/Utils", "sap/ushell/Container" ], function(UIComponent, Utils, Container) { "use strict"; return UIComponent.extend("analytics.Component", { metadata: { manifest: "json" }, init: function() { UIComponent.prototype.init.apply(this, arguments); Utils.setCommonResource(this); const oCommonI18nModel = this.getModel("i18n"); const sNewTitle = oCommonI18nModel.getText("common.analyticsTitle"); const sNewDesc = oCommonI18nModel.getText("common.analyticsDesc"); // 获取FLP的LaunchPage服务 const oLaunchPageService = Container.getService("LaunchPage"); if (oLaunchPageService) { // 获取所有分组和Tile,找到当前应用对应的Tile oLaunchPageService.getGroups().then((aGroups) => { aGroups.forEach((oGroup) => { const aTiles = oGroup.getTiles(); aTiles.forEach((oTile) => { // 匹配当前应用的ID(从manifest中获取) if (oTile.getTargetURL().includes(this.getManifestEntry("sap.app").id)) { oTile.setTitle(sNewTitle); oTile.setDescription(sNewDesc); } }); }); }); } } }); });
这个方法依赖Fiori Launchpad的环境,不适合独立运行的应用,而且匹配Tile的逻辑可能需要根据你的FLP配置调整(比如用语义对象+动作来匹配)。
内容的提问来源于stack exchange,提问作者Tina Chen
相关产品推荐
相关产品推荐

