Javascript 如何在UI5中等待JSONModel.loadData()请求
在SAPUI5/OpenUI5中,我有一个JSONModel,由服务器上的一个文件填充: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
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的构造函数时,APIloadData
也在内部调用。在这种情况下,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");