OData Model Not Working

2019-02-19 00:12发布

I am trying to use expand option in my XML view but it's resulting no data.

Screenshot No Data

Data are coming from backend as I can see in debugging under 'Network' option but there seems to be some binding issue in XML view.

Component.js

sap.ui.define([
    "sap/ui/core/UIComponent",
    "sap/ui/Device",
    "sem/stock_app/model/models"
], function(UIComponent, Device, models) {
    "use strict";

    return UIComponent.extend("sem.stock_app.Component", {

        metadata: {
            manifest: "json"
        },

        /**
         * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
         * @public
         * @override
         */
        init: function() {
            var url = "/sap/opu/odata/sap/ZMATLIST_SRV_02";
            var odata = new sap.ui.model.odata.ODataModel(url, {
                json: true
            });
            this.setModel(odata);
            UIComponent.prototype.init.apply(this, arguments);
            this.getRouter().initialize();
            this.setModel(models.createDeviceModel(), "device");
        }
    });
});

manifest.json

{
    "_version": "1.7.0",
    "sap.app": {
        "id": "sem.stock_app",
        "type": "application",
        "i18n": "i18n/i18n.properties",
        "applicationVersion": {
            "version": "1.0.0"
        },
        "title": "{{appTitle}}",
        "description": "{{appDescription}}",
        "sourceTemplate": {
            "id": "ui5template.basicSAPUI5ApplicationProject",
            "version": "1.40.12"
        }
    },
    "sap.ui": {
        "technology": "UI5",
        "icons": {
            "icon": "",
            "favIcon": "",
            "phone": "",
            "phone@2": "",
            "tablet": "",
            "tablet@2": ""
        },
        "deviceTypes": {
            "desktop": true,
            "tablet": true,
            "phone": true
        },
        "supportedThemes": [
            "sap_hcb",
            "sap_belize"
        ]
    },
    "sap.ui5": {
        "rootView": {
            "viewName": "sem.stock_app.view.mat",
            "type": "XML"
        },
        "dependencies": {
            "minUI5Version": "1.30.0",
            "libs": {
                "sap.ui.core": {},
                "sap.m": {}
            }
        },
        "contentDensities": {
            "compact": true,
            "cozy": true
        },
        "models": {
            "i18n": {
                "type": "sap.ui.model.resource.ResourceModel",
                "settings": {
                    "bundleName": "sem.stock_app.i18n.i18n"
                }
            }
        },
        "resources": {
            "css": [{
                "uri": "css/style.css"
            }]
        },
        "routing": {
            "config": {
                "routerClass": "sap.m.routing.Router",
                "viewType": "XML",
                "viewPath": "sem.stock_app.view",
                "controlId": "idAppControl",
                "controlAggregation": "pages"
            },
            "routes": [{
                "name": "r1",
                "pattern": "",
                "target": "t1"
            },
                {
                    "name": "r2",
                    "pattern": "page2/{noti}",
                    "target": "t2"
                }],
            "targets": {
                "t1": {
                    "viewName": "mat",
                    "viewId": "idmat",
                    "controlAggregation": "pages",
                    "viewLevel": 1
                },
                "t2": {
                    "viewName": "table",
                    "viewId": "idtable",
                    "controlAggregation": "pages",
                    "viewLevel": 2
                }
            }
        }
    }
}

Root View

<mvc:View
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    controllerName="sem.stock_app.controller.mat"
    displayBlock="true"
>
    <App id="idAppControl">
        <Page title="Material Input">
            <Label text="Material Selection"/>
            <Input id="materialInput"
                type="Text"
                width="50%"
                placeholder="Enter Material"
                showSuggestion="true"
                showValueHelp="false"
                valueHelpRequest="handleValueHelp"
                submit="onSubmit"
                suggestionItems="{/matlistSet}"
            >
                <suggestionItems>
                    <core:Item text="{Matid}"/>
                </suggestionItems>
            </Input>
            <Button text="Get Details" enabled="true" press="myPress"/>
        </Page>
    </App>
</mvc:View>

Table View

<mvc:View
    xmlns:core="sap.ui.core"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m"
    controllerName="sem.stock_app.controller.table"
>
    <App id="tableApp">
        <Page
            title="Table"
            showNavButton="true"
            navButtonPress="onNavBack"
        >
            <Table
                growing="true"
                items="{
                    path: 'odata>/matlistSet',
                    parameters: {
                        expand: 'NP_ON_MATID'
                    }
                }"
                itemPress="onListItemPressed"
                width="100%"
                mode="MultiSelect"
            >
                <columns>
                    <Column>
                        <Text text="Material ID"/>
                    </Column>
                    <Column>
                        <Text text="Category"/>
                    </Column>
                    <Column>
                        <Text text="Material Desc"/>
                    </Column>
                    <Column>
                        <Text text="Plant"/>
                    </Column>
                </columns>
                <items>
                    <ColumnListItem type="Active">
                        <Text text="{odata>NP_ON_MATID/Matid}"/>
                        <Text text="{odata>NP_ON_MATID/Category}"/>
                        <Text text="{odata>NP_ON_MATID/Matdesc}"/>
                        <Text text="{odata>NP_ON_MATID/Plant}"/>
                    </ColumnListItem>
                </items>
            </Table>
        </Page>
    </App>
</mvc:View>

Table Controller

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/core/routing/History"
], function(Controller, History) {
    "use strict";

    return Controller.extend("sem.stock_app.controller.table", {
        onInit: function() {this.getOwnerComponent().getRouter().getRoute("r2").attachPatternMatched(this.mynav, this);
            this.getOwnerComponent().getRouter().setView("table");
        },

        mynav: function(oeve) {
            var data = oeve.getParameters().arguments.noti;
            var params = "('" + data + "')?$expand=NP_ON_MATID";
            var path = "/matlistSet" + params + "";
            this.getView().bindElement(path);
        },

        onNavBack: function(window) {
            var oHistory = History.getInstance();
            var sPreviousHash = oHistory.getPreviousHash();
            if (sPreviousHash !== undefined) {
                window.history.go(-1);
            } else {
                var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
                oRouter.navTo("overview", {}, true);
            }
        },

    });
});

metadata.xml

<?xml version="1.0" encoding="utf-8" ?> 
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:sap="http://www.sap.com/Protocols/SAPData">
    <edmx:DataServices m:DataServiceVersion="2.0">
        <Schema Namespace="ZMATLIST_SRV_02" xml:lang="en" sap:schema-version="1" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
            <EntityType Name="matlist" sap:content-version="1">
                <Key>
                    <PropertyRef Name="Matid" />
                </Key>
                <Property Name="Matid" Type="Edm.String" Nullable="false" MaxLength="18" sap:unicode="false" sap:label="Material" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Category" Type="Edm.String" Nullable="false" MaxLength="20" sap:unicode="false" sap:label="Char20" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Matdesc" Type="Edm.String" Nullable="false" MaxLength="40" sap:unicode="false" sap:label="Char" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Plant" Type="Edm.String" Nullable="false" MaxLength="4" sap:unicode="false" sap:label="Plant" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Status" Type="Edm.String" Nullable="false" MaxLength="20" sap:unicode="false" sap:label="Char20" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Qty" Type="Edm.Decimal" Nullable="false" Precision="13" Scale="3" sap:unicode="false" sap:label="Quantity" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <NavigationProperty Name="NP_ON_MATID" Relationship="ZMATLIST_SRV_02.MATASSOCIATION" FromRole="FromRole_MATASSOCIATION" ToRole="ToRole_MATASSOCIATION" />
            </EntityType>
            <EntityType Name="matdetails" sap:content-version="1">
                <Key>
                    <PropertyRef Name="Matid" />
                </Key>
                <Property Name="Matid" Type="Edm.String" Nullable="false" MaxLength="18" sap:unicode="false" sap:label="Material" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Matitno" Type="Edm.Int32" Nullable="false" sap:unicode="false" sap:label="Number" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Category" Type="Edm.String" Nullable="false" MaxLength="20" sap:unicode="false" sap:label="Char20" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Matdesc" Type="Edm.String" Nullable="false" MaxLength="40" sap:unicode="false" sap:label="Char" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
                <Property Name="Plant" Type="Edm.String" Nullable="false" MaxLength="4" sap:unicode="false" sap:label="Plant" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false" />
            </EntityType>
            <Association Name="MATASSOCIATION" sap:content-version="1">
                <End Type="ZMATLIST_SRV_02.matlist" Multiplicity="1" Role="FromRole_MATASSOCIATION" />
                <End Type="ZMATLIST_SRV_02.matdetails" Multiplicity="*" Role="ToRole_MATASSOCIATION" />
                <ReferentialConstraint>
                    <Principal Role="FromRole_MATASSOCIATION">
                        <PropertyRef Name="Matid" />
                    </Principal>
                    <Dependent Role="ToRole_MATASSOCIATION">
                        <PropertyRef Name="Matid" />
                    </Dependent>
                </ReferentialConstraint>
            </Association>
            <EntityContainer Name="ZMATLIST_SRV_02_Entities" m:IsDefaultEntityContainer="true" sap:supported-formats="atom json xlsx">
                <EntitySet Name="matlistSet" EntityType="ZMATLIST_SRV_02.matlist" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:content-version="1" />
                <EntitySet Name="matdetailsSet" EntityType="ZMATLIST_SRV_02.matdetails" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:content-version="1" />
                <AssociationSet Name="MATASSOCIATIONSet" Association="ZMATLIST_SRV_02.MATASSOCIATION" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:content-version="1">
                    <End EntitySet="matlistSet" Role="FromRole_MATASSOCIATION" />
                    <End EntitySet="matdetailsSet" Role="ToRole_MATASSOCIATION" />
                </AssociationSet>
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

标签: odata sapui5
1条回答
兄弟一词,经得起流年.
2楼-- · 2019-02-19 00:45

TL;DR

Here I created a running example from your code: https://plnkr.co/edit/a2pcO6.

screenshot of https://plnkr.co/edit/a2pcO6

In the production code, remove all mock server references.


Issues to fix

Backend

According to your service metadata, the foreign key inside matdetails is also the only primary key at the same time. I.e. the Matids in matdetails cannot be unique if one matlist is supposed be associated with multiple matdetails entities.

Frontend

Model

  • You missed the model name in setModel.
    • Either pass the model name according to your view: this.setModel(odata, "odata")
    • Or remove the model name from everywhere. E.g.: <Text text="{Matid}"/>
  • According to your screenshot, the response body of your entity set doesn't contain the property "results" which ODataModel cannot deal with. Same as this issue, the "response" property needs to be there in each collection so that UI5 can display the items correctly. Not sure about the cause though as I don't have any expertise in backend. Having all entities uniquely identifiable might resolve this problem.
  • Also worth reading: Stop Using sap.ui.model.odata.ODataModel

UI

  • You're instantiating your root view (and its controller) twice. Please, avoid that. Read:
  • Remove the second <App> from your table view. An application should contain only one root element. If not, you might end up having this kind of problems.
  • Since you want to display matdetails entities of selected matlist entity in the table, binding items there with the absolute path /matlistSet doesn't make sense. So, replace ..

    items="{
      path: 'odata>/matlistSet',
      parameters: {
        expand: 'NP_ON_MATID'
      }
    }"
    

    .. with just items="{odata>NP_ON_MATID}". This binding is now relative. The property NP_ON_MATID will be resolved once the selected context is given which is done in the controller..

Controller

  • On patternMatched, the selected Matid value is given. So far so good but there are two anti-patterns in the following lines:

    var params = "('" + data + "')?$expand=NP_ON_MATID";
    var path = "/matlistSet" + params + "";
    
    1. Avoid creating entity key(s) manually.
    2. Avoid appending ?$expand manually as it won't expand the entity. Pass the navigation property to the parameters/expand of bindElement instead.
  • Off-topic but if you want to navigate back: Remove window parameter from onNavBack: function(window) { ... }. Otherwise, the window in window.history.go is not the global window object but the press event from the back button.

查看更多
登录 后发表回答