oData模型的SAP UI5访问值

SAP UI5 access value of oData model

这几周我开始使用 SAPUI5 并构建了我的第一个显示一些数据的应用程序。我什至设法做了一些过滤,但现在我遇到了一个我不明白的错误。

我的 oData 模型具有以下结构:

Notice('0000'):
  Value0: abc
  Value1: def
  Value2: ghi


Notice('0001'):
  Value0: abc
  Value1: def
  Value2: ghi

我有一个 table 保存数据:

<Table
    id="noticeList"
    class="sapUiResponsiveMargin"
    width="auto"
    items="{
        path : '/Notice',
        sorter : {
            path : 'Value0'
        }
    }">

...一些 header 内容和列声明...

      <items>
        <ColumnListItem
             id="noticeColumnListItem"
             items="{
                path : '/Notice'
            }">
            <cells>
                <ObjectStatus text="{Value0}"/>
                <ObjectStatus text="{Value1}"/>
                <ObjectStatus text="{Value2}"/>
           </cells>
        </ColumnListItem>
    </items>
</Table>

现在,我想访问我的模型的数据(无论是在渲染之前还是之后)。我没有触发此事件的事件,我只需要模型数据传输后的信息。

所以我搜索了一下,发现了以下内容:

var myValue = this.byId("noticeList").getModel().getProperty("/Notice/Value0");

我尝试了所有可能的路径,但总是以 myValue 未定义而告终。当我转储我的模型时,我可以看到它包含一个具有所需值的 object oData。此外,我的列表显示正确,但我无法从模型中读取单个值。

这就是我在 Component.js 中实例化它的方式:

config: {
    fullWidth: true,
    resourceBundle: "i18n/messageBundle.properties",
    serviceConfig: {
        name: "MYJOBS",
        serviceUrl: "/sap/opu/odata/sap/PATH_TO_SERVICE"
    }
},

// Read service URL
var sServiceUrl = mConfig.serviceConfig.serviceUrl;

// Create and set domain model to the component

var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, {
    json: true,
    loadMetadataAsync: true
});

oModel.attachMetadataFailed(function() {
    sap.ui.getCore().getEventBus().publish("Component", "MetadataFailed");
}, this);

//var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl);
this.setModel(oModel);

也许我还应该提一下,我不使用 index.html 来加载应用程序,而是通过 Fiori Launchpad 和 Component.js

我在这个问题上花了好几个小时都找不到解决办法,希望有人能帮忙...

亲切的问候!

首先,我希望我能把一切都弄好,最后你能明白我的意思:-)

为了文件夹等的正确元素结构,您应该获得 Web 的试用版 IDE 并使用模板 "SAPUI5"。不要小看结构:-)

您的应用程序的结构应该是:
父文件夹
webapp 文件夹
现在处于同一级别:component.js / index.html 和文件夹(例如,对于视图和控制器或 i18n)

1) Component.js / manifest.json(在较新的版本 > 1.32 中)
--> 它仅包含有关模型实例化、国际化实例、服务 url、目标和路由模式的信息。此处没有模型加载!

config: {
    fullWidth : true,
    resourceBundle: "i18n/messageBundle.properties",
    serviceConfig: {
        type: "OData",  // type is missing
        uri: "/sap/opu/odata/sap/PATH_TO_SERVICE" // use uri as property
    }

},

2) 控制器(在 onInit-hook-method 中)

 onInit: function() {

   var sServiceUrl = "/sap/opu/odata/sap/yourPathSRV/";
   var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl);
   this.getView().setModel(oModel);

}

3) 查看(内容区)

<mvc:View controllerName="TEST.controller.Main"
   xmlns:l="sap.ui.layout"
   xmlns:mvc="sap.ui.core.mvc" 
   xmlns="sap.m">
 <App>
  <pages>
   <Page title="{i18n>title}">
    <content>
    <List id="yourListId" items="{/Notice}">
      <StandardListItem description="{Value0}" title="{Value1}"/>
     </List>
    </content>
   </Page>
  </pages>
 </App>
</mvc:View>

4) 后端

--> 你需要实现 GET_ENTITYSET - 读取 "multiple" notice-entities 的方法 :-)

如果您正在调用远程服务,导致未定义情况的最常见原因是在返回数据时出现延迟,而其他代码继续执行(因为您正在异步调用您的服务)。

如果您尝试对返回的数据进行操作,则可以通过以下方式附加事件侦听器/匿名函数来执行此操作:

oModel.attachRequestCompleted(function(){
                    // do something
                });

在您的场景中,您的控制器代码可以更改为如下所示:

 onInit: function() {

   var sServiceUrl = "/sap/opu/odata/sap/yourPathSRV/";
   var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl);
   oModel.attachRequestCompleted(function(){
                    // do something
                });
   this.getView().setModel(oModel);
}

Bernard 的回答是解决问题的答案!

问题是我过早地尝试访问数据。 我已经尝试通过使用自建的睡眠功能来避免这种情况,但是失败了(因为睡眠只是延长了请求时间)。

这已经成功了:

this.byId("noticeList").getModel().attachRequestCompleted(function(oEvent){

    var model = oEvent.getSource();

    var myNeededValue = model.getProperty("/NoticeSet('0001')/Value0"));

});

非常感谢!