我维护的 SAP Fiori 应用程序已经运行了两年,没有出现任何问题。将 SAPUI5 从 1.56.x 升级到 1.101.x 后,出现各种错误,这些错误可以追溯到我尝试为 JSON 模型加载数据的位置。
错误是:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'indexOf')
这是代码:
onAfterRendering: function (oEvent) {
var sButtonId = this.getModel("misc").getProperty("/ButtonId");
// ...
// Here the code breaks because the variable is undefined:
if (sButtonId.indexOf("Demand") > -1) {
//...
}
},
该错误通常仅在从 SAP Fiori 启动板导航到应用程序时出现。如果您重新加载应用程序本身,99.9% 的情况下不会发生错误。
没有预先描述或读取变量的调用。第一次使用时会直接出现错误。
我试图调试一下 UI5 框架,并遇到了内部方法 JSONModel.prototype._getObject
:
当我直接调用应用程序时,此方法返回适当的数据并且应用程序可以运行。当我从启动板调用应用程序时,该方法返回 null
。模型尚未加载(oNode === undefined
)。
然后我查看了网络,发现当我直接调用应用程序时,在调用上述函数之前已经加载了 JSON 文件/模型,而当我从启动板加载应用程序时,JSON 文件已被加载已请求,但尚未提供任何内容。
所以这似乎是一个异步问题。我无法使用 async
/await
,因为 UI5 官方仅支持 ECMAScript 5 (ES5),否则我们无法部署。
模型通过应用描述符 (manifest.json
) 声明并预加载。
最佳答案
与 a/61879725 相同或a/63892279 ,您需要使用 JSONModel
中的 dataLoaded
1 重构代码,以确保数据已加载:
// Given: JSONModel and data source declared in the application descriptor (manifest.json)
thatJSONModel.dataLoaded().then(function() { // Ensuring data availability instead of assuming it.
var sButtonId = thatJSONModel.getProperty("/ButtonId"); // sButtonId is now defined.
// ...
}.bind(this));
顺便说一句。我强烈建议应用程序不要依赖 onBeforeRendering
/onAfterRendering
,因为它们无法预测何时和多少次框架或控件启动渲染。2
1 API 引用:sap.ui.model.json.JSONModel#dataLoaded
2 比如最近的commit 8e24738
减少应用程序中渲染调用的数量。
关于javascript - 如何确保 JSONModel 的数据已加载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73829162/