【问题标题】:How to wait for a JSONModel.loadData() request in UI5如何在 UI5 中等待 JSONModel.loadData() 请求
【发布时间】:2016-04-26 10:56:13
【问题描述】:

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

【问题讨论】:

标签: javascript asynchronous xmlhttprequest sapui5


【解决方案1】:

原来.loadData()函数中有一个参数可以创建同步调用:

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

也请参阅API-Reference

【讨论】:

  • 但这可能会导致控制台出现警告,因为不建议使用同步 ajax 请求,因为它们会阻塞 UI。您可以附加到Model.requestCompleted 事件以访问异步加载的数据:oModel.attachRequestCompleted(function() {console.log(oModel.getData());});
  • 文档现在明确警告避免将bAsync 设置为false:github.com/SAP/openui5/commit/…。请避免创建另一个 UI5 已经充满的同步 XHR。对于 UI5 版本≥1.64 的应用,可以使用 Promise:stackoverflow.com/a/63892279/5846045
【解决方案2】:

您可以使用模型中的 attachRequestCompleted-listener [1]

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]

【讨论】:

    【解决方案3】:

    您要查找的关键字是“Deferred”-object --> 它使您能够在 SAPUI5 中等待 AJAX 请求。

    检查 SAPUI5 上下文:SAPUI5 Wait for an Deferred-Object // wait for .done() function

    【讨论】:

      【解决方案4】:

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

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

      oModel.attachRequestCompleted(function() {
              console.log(oModel.getData());
          });
      

      【讨论】:

      • 请注意,如果你在数据加载完成后注册这个事件调用,它不会像promises那样执行它的代码。
      • 没错。由于您可以多次调用 loadData(),因此也可以多次触发该事件。如果 loadData() 会返回一个承诺,那就太好了。但似乎他们不喜欢沃尔多夫的承诺;)
      • 对于我的特殊情况,我打算预加载到全局模型。从本地模型,我无法在加载之前将RequestCompleted附加到全局模型。我也无法从全局访问本地模型。
      • @MartinBraun 自 1.64 起,dataLoaded can be used 为那个。
      【解决方案5】:

      实现此目的的另一种方法是使用 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(...)

      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 的上下文如何变化。

      Event Provider API Reference

      【讨论】:

        【解决方案6】:

        从 UI5 版本 1.64.0 开始,API loadData 返回一个 Promise 实例:

        logLoadedData: async function () {
          const jsonModel = new JSONModel();
          await jsonModel.loadData("<host>/data/config.json");
          console.log(jsonModel.getData()); // after the loadData promise is resolved
        },

        另外,还有 API dataLoaded 也返回一个承诺。当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());
        },

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

        【讨论】:

          猜你喜欢
          • 2015-02-21
          • 1970-01-01
          • 2022-10-01
          • 2021-05-04
          • 1970-01-01
          • 2018-07-19
          • 2021-08-06
          • 2018-11-13
          • 1970-01-01
          相关资源
          最近更新 更多