Javascript 如何在UI5中等待JSONModel.loadData()请求

Javascript 如何在UI5中等待JSONModel.loadData()请求,javascript,asynchronous,xmlhttprequest,sapui5,Javascript,Asynchronous,Xmlhttprequest,Sapui5,在SAPUI5/OpenUI5中,我有一个JSONModel,由服务器上的一个文件填充: var-oModel=newjsonmodel(); oModel.loadData(“http://127.0.0.1/data/config.json"); log(JSON.stringify(oModel.getData()); 由于请求是异步的,因此控制台记录未定义的。如何使其同步,以便在加载数据后调用控制台.log()?结果是.loadData()函数中有一个参数用于创建同步调用: oMode

在SAPUI5/OpenUI5中,我有一个JSONModel,由服务器上的一个文件填充:

var-oModel=newjsonmodel();
oModel.loadData(“http://127.0.0.1/data/config.json");
log(JSON.stringify(oModel.getData());

由于请求是异步的,因此控制台记录未定义的
。如何使其同步,以便在加载数据后调用
控制台.log()

结果是
.loadData()
函数中有一个参数用于创建同步调用:

oModel.loadData("http://127.0.0.1/data/config.json", "", false);

另请参见。

您可以从模型中使用attachRequestCompleted侦听器

另一个要使用的函数是

$.get(url, function(response){
    console.log(response);
    model.setData(response);
});
// or
$.ajax(url, {
    success: function(){
        console.log(response);
        model.setData(response);
    }
});

这样做的好处是,您可以使用jQuery.ajax接受的每个设置配置请求。您要查找的关键字是“Deferred”-object-->它允许您在SAPUI5中等待ajax请求


检查SAPUI5上下文:

不建议使用同步ajax请求,因为它会阻塞UI,并可能导致控制台中出现警告

您可以附加到事件以访问异步加载的数据:


实现这一点的另一种方法是使用EventProvider中的
attachEventOnce
方法

oModel.attachEventOnce("requestCompleted", function(oEvent) {
    console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this);
当您只需要响应一个请求而不是所有请求时,最好使用这种方法。否则,如果使用
oModel.attachRequestCompleted(…)
,则所有请求都将通过相同的处理函数

您还可以使用方法链接来简化此操作

oModel.attachEventOnce(…)
返回调用该方法的对象,因此您可以在一条语句中加载数据并处理回调

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(…)

这将执行
loadData()
请求、控制台响应以及控制台所有后续请求的响应

注意:在回调函数中使用此时要小心。如果未将
this
作为
attachRequestCompleted(…)
AttachEventance(…)
方法的参数传递,则
this
将失去作为控制器的原始上下文,并继承调用函数的对象的上下文。herrlock的回答说明了
的上下文是如何变化的


自UI5 1.64.0版以来,API返回一个承诺实例:

logLoadedData:asyncfunction(){
var-oModel=new-JSONModel();
waitoModel.loadData(“/data/config.json”);
console.log(oModel.getData(data));//解析loadData承诺后
},
或者,还有一个API,它也返回一个承诺。它将在
loadData
发送的所有请求完成时解析。以下是不带async Wait的语法:

doSomethingWith:function(jsonModel){
//不确定模型是否已加载所有数据?只需使用dataLoaded:
jsonModel.dataLoaded()。然后(/*fnDoThat*/);
},

当使用字符串(URL)作为参数调用JSONModel的构造函数时,API
loadData
也在内部调用。在这种情况下,
dataLoaded
可能也会派上用场。

但这可能会导致控制台中出现警告,因为不建议使用同步ajax请求,因为它们会阻塞UI。您可以附加到
Model.requestCompleted
事件以访问异步加载的数据:
oModel.attachRequestCompleted(function(){console.log(oModel.getData());})文档现在明确警告不要将
bAsync
设置为
false
:。请避免创建另一个UI5已满的同步XHR。对于使用UI5版本的应用程序≥ 1.64,可以使用承诺:请注意,如果在加载数据后注册此事件调用,它将不会像承诺那样执行其代码。没错。由于可以多次调用loadData(),因此也可以多次触发该事件。如果loadData()能够返回一个承诺,那就太好了。但他们似乎不喜欢沃尔多夫的承诺;)对于我的特殊情况,我打算预加载到全局模型。从本地模型中,我无法在加载全局模型之前将其附加到全局模型。我也无法从全局端访问本地模型。@MartinBraun,因为1.64版本。对于使用UI5 1.64及以上版本的读者:现在。
oModel.attachEventOnce("requestCompleted", function(oEvent) {
    console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this);
oModel.attachEventOnce("requestCompleted", function(oEvent) {
    console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this).loadData("http://127.0.0.1/data/config.json");
oModel.attachRequestCompleted(function(oEvent) {
    console.log(JSON.parse(oEvent.getParameter("response").responseText));
}, this).loadData("http://127.0.0.1/data/config.json");