简体   繁体   English

UI5 / Fiori 加载 JSON Model

[英]UI5 / Fiori loading a JSON Model

I maintain a Fiori app that has been running for 2 years without any problems.我维护了一个已经运行了 2 年没有任何问题的 Fiori 应用程序。 Suddenly there are various errors that can be traced back to a place where I try to load a local JSON model.突然有各种错误可以追溯到我尝试加载本地 JSON model 的地方。

The error is错误是

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'indexOf') Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'indexOf')

This is the code这是代码

var sSelectedFilterButtonId = this.getModel("misc").getProperty("/ButtonId");
[... more stuff]
if (sSelectedFilterButtonId.indexOf("Demand") > -1) { ... >>>> error

I'm not a JS pro and suspect that loading the model is asynchronous (as the error said "In Promise").我不是 JS 专业人士,我怀疑加载 model 是异步的(正如错误所说的“In Promise”)。 But there is nothing about this or any async in the UI5 API.但是在 UI5 API 中没有任何关于这个或任何异步的内容。 It has worked for the last few years.在过去的几年里,它一直有效。 Can someone explain this to me?谁可以给我解释一下这个? Or do I have to proceed differently here?还是我必须在这里以不同的方式进行?

Even more strange is that the error usually only appears when navigating to the app from the Fiori Launchpad.更奇怪的是,该错误通常仅在从 Fiori Launchpad 导航到应用程序时才会出现。 If you reload the app itself, 99.9% of the time no error occurs....如果您重新加载应用程序本身,则 99.9% 的时间不会发生错误......

Edit (new informations):编辑(新信息):

I was trying to debug the UI5 framework a bit and came across method JSONModel.prototype._getObject.我试图调试 UI5 框架并遇到了 JSONModel.prototype._getObject 方法。

在此处输入图像描述

This method should load the data from the JSON model.此方法应从 JSON model 加载数据。 When I call the app directly, this function returns the appropriate data and the app works.当我直接调用应用程序时,这个 function 返回适当的数据并且应用程序工作。 When I call the app from the launchpad, the function returns null.当我从启动板调用应用程序时,function 返回 null。 The model has not been loaded yet. model 尚未加载。 oNode === undefined

I then looked at the network and found that when I call the app directly, the JSON file/model has already been loaded before the above function is called.然后查看网络,发现直接调用app时,在调用上述function之前,已经加载了JSON文件/模型。

When I load the app from the launchpad, the JSON file has been requested but no content has been served yet.当我从启动板加载应用程序时,已请求 JSON 文件,但尚未提供任何内容。 The file is still empty, so of course I get a null... So it seems to be an asynchronous problem.该文件仍然是空的,所以我当然得到了一个null......所以它似乎是一个异步问题。 If I set the "async" properties in the manifest to false, the app is not opened from the launchpad at all... I cannot use async/await, because UI5 officially only supports ECMAScript 5 and we cannot deploy otherwise...如果我将清单中的“异步”属性设置为 false,则根本不会从启动板打开应用程序...我无法使用 async/await,因为 UI5 官方仅支持 ECMAScript 5,否则我们无法部署...

There is no call that describes or reads the variable beforehand.没有预先描述或读取变量的调用。 The error appears directly at the first use.错误在第一次使用时直接出现。

In the onInit() method only a local variable is set.onInit()方法中只设置了一个局部变量。 Nothing special.没什么特别的。

onAfterRendering: function (oEvent) {
    // getting filter values
    var sButtonId = this.getModel("misc").getProperty("/ButtonId");

    var aFilters = this._calcInternalStuff(null, null, null);
    var oBinding = null;

    // Here the code breaks because the variable is undefined.
    // Please do not ask who or what has thought up your logic here...
    if (sButtonId.indexOf("Demand") > -1) {
        oBinding = this._oDemandsTable.getBinding("items");
    } else {
        oBinding = this._oRecallsTable.getBinding("items");
    }
    if (oBinding !== null && oBinding !== undefined) {
        oBinding.filter(null);
        oBinding.filter(aFilters);
    }
}, //END onAfterRendering()

Same as a/61879725 or a/63892279 , you'll need to refactor the code by using dataLoaded 1 from the JSONModel to ensure that the data have been loaded:a/61879725a/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));

Btw.顺便提一句。 I'd strongly discourage applications from relying on onBeforeRendering / onAfterRendering since it's unpredictable for them when and how many times the framework or a control initiates rendering.我强烈反对应用程序依赖onBeforeRendering / onAfterRendering ,因为它们无法预测框架或控件何时以及多少次启动渲染。 2 2


1 API Reference: sap.ui.model.json.JSONModel#dataLoaded 1 API 参考: sap.ui.model.json.JSONModel#dataLoaded
2 For example, the recent commit 8e24738 reduces the number of render calls in applications. 2例如,最近的提交8e24738减少了应用程序中的渲染调用次数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM