如何在 UI5 中等待 JSONModel.loadData() 请求
How to wait for a JSONModel.loadData() request in UI5
在 SAPUI5/OpenUI5 中,我有一个 JSONModel
我用来自服务器的文件填充:
var oModel = new JSONModel();
oModel.loadData("http://127.0.0.1/data/config.json");
console.log(JSON.stringify(oModel.getData()));
控制台记录 undefined
因为请求是异步的。
如何使其同步以便在加载数据后调用 console.log()
?
原来 .loadData()
函数中有一个参数用于创建同步调用:
oModel.loadData("http://127.0.0.1/data/config.json", "", false);
另见 API-Reference。
您可以使用模型 [1]
中的 attachRequestCompleted-listener
model.attachRequestCompleted(function(){
console.log(this.getData()); //"this" is the model
});
另一个要使用的函数是
$.get(url, function(response){
console.log(response);
model.setData(response);
});
// or
$.ajax(url, {
success: function(){
console.log(response);
model.setData(response);
}
});
这样做的好处是您可以使用 jQuery.ajax 接受的每个设置来配置请求 [2]
您要查找的关键字是 "Deferred"-object --> 它使您能够在 SAPUI5 中等待 AJAX 请求。
检查 SAPUI5 上下文:SAPUI5 Wait for an Deferred-Object // wait for .done() function
不推荐使用同步 ajax 请求,因为它会阻塞 UI 并且可能会导致控制台出现警告。
您可以附加到 Model.requestCompleted
事件以访问异步加载的数据:
oModel.attachRequestCompleted(function() {
console.log(oModel.getData());
});
实现此目的的另一种方法是使用 EventProvider 中的 attachEventOnce
方法。
oModel.attachEventOnce("requestCompleted", function(oEvent) {
console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this);
当您只需要响应一个请求而不是所有请求时,最好使用这种方法。否则,如果您使用 oModel.attachRequestCompleted(...)
,所有请求都将通过相同的处理函数。
您还可以使用方法链来简化此过程。
oModel.attachEventOnce(...)
returns 调用该方法的对象,因此您可以在一条语句中加载数据和处理回调。
oModel.attachEventOnce("requestCompleted", function(oEvent) {
console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this).loadData("http://127.0.0.1/data/config.json");
这将首先执行 loadData()
请求,然后在请求完成后控制台响应。它只会在第一次发出请求时使用回调函数。后续请求将不会通过回调函数。
如果您希望所有请求都通过相同的回调函数,您可以做同样的事情,但使用 oModel.attachRequestCompleted(...)
oModel.attachRequestCompleted(function(oEvent) {
console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this).loadData("http://127.0.0.1/data/config.json");
这将执行 loadData()
请求,控制响应,并控制所有后续请求的响应。
注意:在回调函数中使用 this
时要小心。如果你不将 this
作为 attachRequestCompleted(...)
或 attachEventOnce(...)
方法的参数传递,那么 this
将失去它作为控制器的原始上下文,并继承调用函数的对象。 herrlock 的回答演示了 this
的上下文是如何变化的。
从 UI5 版本 1.64.0 开始,API loadData
returns 一个 Promise 实例:
logLoadedData: <strong>async</strong> 函数 () {
const jsonModel = new JSONModel();
<strong>等待</strong> jsonModel.loadData("<em><主机></em>/data/config.json");
console.log(jsonModel.getData()); // 在 loadData 承诺被解析之后
},
或者,还有 API dataLoaded
也是 returns 一个承诺。当 loadData
发送的所有请求都完成时,它将解决。这是没有 async-await 的语法:
doSomethingWith: async function (jsonModel) {
// Not sure if the model has all data loaded? Just use dataLoaded:
await jsonModel.dataLoaded();
console.log(jsonModel.getData());
},
API loadData
也是在调用 JSONModel
的构造函数时以字符串 (URL) 作为参数在内部调用的。在这种情况下,dataLoaded
可能也会派上用场。
在 SAPUI5/OpenUI5 中,我有一个 JSONModel
我用来自服务器的文件填充:
var oModel = new JSONModel();
oModel.loadData("http://127.0.0.1/data/config.json");
console.log(JSON.stringify(oModel.getData()));
控制台记录 undefined
因为请求是异步的。
如何使其同步以便在加载数据后调用 console.log()
?
原来 .loadData()
函数中有一个参数用于创建同步调用:
oModel.loadData("http://127.0.0.1/data/config.json", "", false);
另见 API-Reference。
您可以使用模型 [1]
中的 attachRequestCompleted-listenermodel.attachRequestCompleted(function(){
console.log(this.getData()); //"this" is the model
});
另一个要使用的函数是
$.get(url, function(response){
console.log(response);
model.setData(response);
});
// or
$.ajax(url, {
success: function(){
console.log(response);
model.setData(response);
}
});
这样做的好处是您可以使用 jQuery.ajax 接受的每个设置来配置请求 [2]
您要查找的关键字是 "Deferred"-object --> 它使您能够在 SAPUI5 中等待 AJAX 请求。
检查 SAPUI5 上下文:SAPUI5 Wait for an Deferred-Object // wait for .done() function
不推荐使用同步 ajax 请求,因为它会阻塞 UI 并且可能会导致控制台出现警告。
您可以附加到 Model.requestCompleted
事件以访问异步加载的数据:
oModel.attachRequestCompleted(function() {
console.log(oModel.getData());
});
实现此目的的另一种方法是使用 EventProvider 中的 attachEventOnce
方法。
oModel.attachEventOnce("requestCompleted", function(oEvent) {
console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this);
当您只需要响应一个请求而不是所有请求时,最好使用这种方法。否则,如果您使用 oModel.attachRequestCompleted(...)
,所有请求都将通过相同的处理函数。
您还可以使用方法链来简化此过程。
oModel.attachEventOnce(...)
returns 调用该方法的对象,因此您可以在一条语句中加载数据和处理回调。
oModel.attachEventOnce("requestCompleted", function(oEvent) {
console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this).loadData("http://127.0.0.1/data/config.json");
这将首先执行 loadData()
请求,然后在请求完成后控制台响应。它只会在第一次发出请求时使用回调函数。后续请求将不会通过回调函数。
如果您希望所有请求都通过相同的回调函数,您可以做同样的事情,但使用 oModel.attachRequestCompleted(...)
oModel.attachRequestCompleted(function(oEvent) {
console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this).loadData("http://127.0.0.1/data/config.json");
这将执行 loadData()
请求,控制响应,并控制所有后续请求的响应。
注意:在回调函数中使用 this
时要小心。如果你不将 this
作为 attachRequestCompleted(...)
或 attachEventOnce(...)
方法的参数传递,那么 this
将失去它作为控制器的原始上下文,并继承调用函数的对象。 herrlock 的回答演示了 this
的上下文是如何变化的。
从 UI5 版本 1.64.0 开始,API loadData
returns 一个 Promise 实例:
logLoadedData: <strong>async</strong> 函数 () {
const jsonModel = new JSONModel();
<strong>等待</strong> jsonModel.loadData("<em><主机></em>/data/config.json");
console.log(jsonModel.getData()); // 在 loadData 承诺被解析之后
},
或者,还有 API dataLoaded
也是 returns 一个承诺。当 loadData
发送的所有请求都完成时,它将解决。这是没有 async-await 的语法:
doSomethingWith: async function (jsonModel) {
// Not sure if the model has all data loaded? Just use dataLoaded:
await jsonModel.dataLoaded();
console.log(jsonModel.getData());
},
API loadData
也是在调用 JSONModel
的构造函数时以字符串 (URL) 作为参数在内部调用的。在这种情况下,dataLoaded
可能也会派上用场。