SAPUI5/OpenUI5:在onInit函数中完成模型附加请求

SAPUI5/OpenUI5:在onInit函数中完成模型附加请求,sapui5,Sapui5,我在Component.js中定义了两个模型。一个是所有联系人的列表,另一个只是已登录的联系人。现在,我想在控制器中检查登录的联系人是否已存在于所有联系人列表中。我将列表中的registrationToken与登录联系人中的token进行比较。但当我循环遍历列表时,由于异步通信,长度为0。 我看到attachRequestCompleted函数,但现在我遇到了另一个问题。。。“附加”功能为“填充视图模型”时,onInit功能已完成 onInit : function(){ var gLo

我在Component.js中定义了两个模型。一个是所有联系人的列表,另一个只是已登录的联系人。现在,我想在控制器中检查登录的联系人是否已存在于所有联系人列表中。我将列表中的registrationToken与登录联系人中的token进行比较。但当我循环遍历列表时,由于异步通信,长度为0。 我看到attachRequestCompleted函数,但现在我遇到了另一个问题。。。“附加”功能为“填充视图模型”时,onInit功能已完成

onInit : function(){
    var gLocalContact = sap.ui.getCore().getModel("gLocalContact");
    var gRemoteContacts = sap.ui.getCore().getModel("gRemoteContacts");

    gRemoteContacts.attachRequestCompleted( function() {
        ... if ... setProperty to gLocalContact.getProperty("/registrationToken")...
        console.log("I should be the first log to get the data in view");
    });

    console.log("I should be the second log!");
    this.getView().setModel(gLocalContact, "localContact");
}

attach函数中的第一个日志应该是第一个日志,因为在这里我定义了一些在视图中需要的gLocalContact数据。另一个问题是我无法访问gLocalContact变量……

这有点难看,因为SAPUI5不支持承诺。因此,在视图中,您不知道是将触发requestCompleted事件,还是数据已经加载。我想到了一些解决办法:

  • 在调用loadData()之前,在组件中附加requestCompleted eventhandler。然后,您就可以成为舒尔,您将获得该活动。 但是,您必须构建视图来处理空的gLocalContact模型。但是,一旦模型中填充了数据,绑定就会更新视图

  • 将onInit()的剩余内容放入eventhander。为了确保获取事件,请检查模型中是否已经有数据,如果已经有数据,请手动调用eventhandler使其至少运行一次

  • 使用jQuerys承诺进行同步。这也允许您等待第二个型号:

  • onInit:function(){
    var gLocalContact=sap.ui.getCore().getModel(“gLocalContact”);
    var gremoteconts=sap.ui.getCore().getModel(“gremoteconts”);
    log(“等待几秒钟数据…”);
    var localContactPromise=this.getPromise(gLocalContact,“/origin”);
    localContactPromise.done(函数(){
    //代码与之前相同,但这次您可以被称为舒尔its。
    //…如果…将属性设置为
    //gLocalContact.getProperty(“/registrationToken”)。。。
    log(“我应该是第一个查看数据的日志”);
    });
    var remotecontacts promise=this.getPromise(gremoteconts,“/origin”);//等待另一个模型
    $.when(localContactPromise,remoteContactsPromise).done(function(){
    //当两个模型都加载时,请执行此操作
    log(“我应该是第二个日志!”);
    this.getView().setModel(gLocalContact,“localContact”);
    此.byId(“标签”).setText(“全部加载”);
    }.约束(这个);
    },
    getPromise:函数(oModel、pathToTestForData){
    var deferred=$.deferred();
    if(oModel.getProperty(pathToTestForData))
    deferred.resolve();//数据已加载
    其他的
    oModel.attachRequestCompleted(deferred.resolve);//正在等待事件
    延迟返回。承诺();
    }
    
    满满的

    Promise
    是具有已完成事件的对象。
    Deferred
    是一个对象,它有一个
    Promise
    和一个
    resolve()
    方法,该方法将引发该Promise上的done事件。如果您首先在延迟上调用
    resolve()
    ,然后为
    done
    注册处理程序,则会立即调用该处理程序。因此,即使比异步加载请求慢,也不会错过该事件


    但是:如果在视图初始化时甚至无法在组件/核心上设置模型,则会出现严重问题,因为不存在modelChanged事件。我建议创建一个空模型,并在components init方法中将其分配给该组件,然后在该模型上使用
    loadData()

    感谢您的回答,我尝试过,但尚未解决。我发现,当我只记录json模型时,我可以看到数据。当我使用console.log(jsonModel.oData)时;或者console.log(jsonModel.oData.length);它是空对象或未定义。当我在我的attachRequestCompleted函数中使用这个函数时,它工作得很好,但是jsonModel2.getProperty()是空的。也许第二个模型还没有完成加载,而第一个模型已经完成了?你试过我的第三种解决方案了吗?有了承诺,您可以轻松地等待多个异步请求。我尝试了您的JSBin,但我还没有在我的项目中实现它。。。我将尝试了解它是如何工作的,您可以找到许多jQuery Promises的示例。例如