javascript - 如何确保 JSONModel 的数据已加载?

标签 javascript sapui5 sap-fiori

我维护的 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 :

Screenshot of sap.ui.model.json.JSONModel#_getObject source code

当我直接调用应用程序时,此方法返回适当的数据并且应用程序可以运行。当我从启动板调用应用程序时,该方法返回 null。模型尚未加载(oNode === undefined)。

然后我查看了网络,发现当我直接调用应用程序时,在调用上述函数之前已经加载了 JSON 文件/模型,而当我从启动板加载应用程序时,JSON 文件已被加载已请求,但尚未提供任何内容。

所以这似乎是一个异步问题。我无法使用 async/await,因为 UI5 官方仅支持 ECMAScript 5 (ES5),否则我们无法部署。

模型通过应用描述符 (manifest.json) 声明并预加载。

最佳答案

a/61879725 相同或a/63892279 ,您需要使用 JSONModel 中的 dataLoaded1 重构代码,以确保数据已加载:

// 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/

相关文章:

javascript - 如何将数据从母版页传递到详细信息页SAPUI5?

data-binding - 自定义 UI5 控件不更新绑定(bind)值

javascript - 如何在 Angular 5 中使用 javaScript TimeSheet 插件

c# - Sys.WebForms.PageRequestManagerServerErrorException : An unknown error occurred while processing the request on the server.“

javascript - 调试在图库中复制较大图像的 Javascript 代码。

css - 如何使用 SAPUI5 更改表中 td 的样式类

sapui5 - 堆积柱与线结合

OData Binding 扩展参数一对多关系

sapui5 - 如何创建SAP Fiori自定义启动板?

javascript - 如何从 Reactjs onPaste 事件中获取粘贴值