0
votes

I have a struggling with my table and it's data, let me give you some context info, I'm using the version 1.72.3, my app is a standalone app hosted in a Nginx, all proxies are in place and working fine.

I have a View like a worklist (a view with one table) and I need to query the back-end using filters but JSONModel not allow it so my idea was simple

  • I create a propetry in JSONModel called "salesOrders"
  • using the event attachPatternMatched I call the back-end using oDataModel
  • I set the property "salesOrders" with the result of oDataModel's call
  • I bind my table to the property

I place all the code but my best result on screen was enter image description here

This is the definition of my table in the view.

<Table noDataText="Drop column list items here and columns in the area above" items="{salesOrderListView>/salesOrders}"
    id="tableSalesOrders" growingScrollToLoad="true" sticky="ColumnHeaders" growing="true">
    <items>
        <ColumnListItem type="Navigation" id="item0" press="onPressSalesOrder">
            <cells>
                <ObjectIdentifier xmlns="sap.m" title="{ path: 'Vbeln', formatter: '.formatter.numberNoZeros' }" titleActive="fasle" id="identifier0"/>
                <Link xmlns="sap.m" text="{Customer/Name1}" id="link0" press="onPressCustomer"/>
                <Link xmlns="sap.m" text="{Vendor/Ename}" id="link1" press="onPressVendor"/>
                <core:Icon src="sap-icon://flag" size="2em" id="icon0" color="{ path: 'Lsstk', formatter: '.formatter.flagStatusColorC' }"/>
                <core:Icon xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:core="sap.ui.core"
                    src="sap-icon://flag" size="2em" id="icon0_copy2" color="{ path: 'Cmgst', formatter: '.formatter.flagStatusColorCred' }"/>
                <core:Icon xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:core="sap.ui.core"
                    src="sap-icon://flag" size="2em" id="icon0_copy" color="{ path: 'Lfstk', formatter: '.formatter.flagStatusColor' }"/>
                <Text xmlns="sap.m" text="{Vdatu}" id="text1"/>
                <ObjectNumber xmlns="sap.m" number="{ path: 'Kwmeng', formatter: '.formatter.numberNoDecimals' }" unit="CJ" id="number0" textAlign="Center"/>
                <ObjectNumber xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m"
                    number="{ path: 'Kwmengdlvy', formatter: '.formatter.numberNoDecimals' }" unit="CJ" id="number0_copy2" textAlign="Center"/>
                <ObjectNumber xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m"
                    number="{ path: 'Kwmengdiff', formatter: '.formatter.numberNoDecimals' }" unit="CJ" id="number0_copy" textAlign="Center"/></cells>
        </ColumnListItem>
    </items>
    <columns>
        <Column id="column0">
            <header>
                <Label text="{i18n>vbelnLabel}" id="label0"/>
            </header>
        </Column>
        <Column id="column1" minScreenWidth="Large" demandPopin="true" popinDisplay="Inline">
            <header>
                <Label text="{i18n>customerName1Label}" id="label1"/>
            </header>
        </Column>
        <Column id="column2" minScreenWidth="Large" demandPopin="true" popinDisplay="Inline" popinHAlign="Left">
            <header>
                <Label text="{i18n>vendorEnameLabel}" id="label2"/>
            </header>
        </Column>
        <Column xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m" id="column2_copy6"
            demandPopin="true">
            <header>
                <Label text="Aprobación Comercial" id="label2_copy6" wrapping="true"/>
            </header>
        </Column>
        <Column xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m" id="column2_copy5"
            demandPopin="true">
            <header>
                <Label text="Aprobación Crediticia" id="label2_copy5" wrapping="true"/>
            </header>
        </Column>
        <Column xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m" id="column2_copy4"
            demandPopin="true">
            <header>
                <Label text="Expedición" id="label2_copy4"/>
            </header>
        </Column>
        <Column xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m" id="column2_copy2">
            <header>
                <Label text="{i18n>vdatuLabel}" id="label2_copy2" wrapping="true"/>
            </header>
        </Column>
        <Column xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m" id="column2_copy"
            minScreenWidth="Large" demandPopin="true" popinDisplay="Inline">
            <header>
                <Label text="{i18n>kwmengLabel}" id="label2_copy" wrapping="true"/>
            </header>
        </Column>
        <Column xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m" id="column2_copy7"
            demandPopin="true" minScreenWidth="Large" popinDisplay="Inline">
            <header>
                <Label text="{i18n>kwmengDlvyLabel}" id="label2_copy7" wrapping="true"/>
            </header>
        </Column>
        <Column xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="sap.m" id="column2_copy3">
            <header>
                <Label text="{i18n>kwmengDiffLabel}" id="label2_copy3" wrapping="true"/>
            </header>
        </Column>
    </columns>
    <headerToolbar>
        <Toolbar width="100%" id="toolbar1">
            <content>
                <Title id="SalesOrderListHeader" text="{salesOrderView>/salesOrderTableTitle}"/>
                <ToolbarSpacer/>
                <SearchField id="searchField" tooltip="{i18n>salesOrderSearchTooltip}" search="onSearch" width="auto"/>
            </content>
        </Toolbar>
    </headerToolbar>
</Table>

An in my controller I have this

sap.ui.define([
    //  "sap/ui/core/mvc/Controller",
    "riders/polux/controller/BaseController",
    "sap/ui/model/json/JSONModel",
    "sap/ui/core/routing/History",
    "riders/polux/model/formatter"
], function (BaseController, JSONModel, History, formatter) {
    "use strict";
    return BaseController.extend("riders.polux.controller.SalesOrderList", {
        formatter: formatter,
        /**
         * Called when a controller is instantiated and its View controls (if available) are already created.
         * Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
         * @memberOf riders.polux.view.SalesOrderList
         */
        onInit: function () {
            var headerTitle, oViewModel, iOriginalBusyDelay, oTable = this.byId("tableSalesOrders");
            // Put down salesOrderList table's original value for busy indicator delay,
            // so it can be restored later on. Busy handling on the table is
            // taken care of by the table itself.
            iOriginalBusyDelay = oTable.getBusyIndicatorDelay();
            // Model used to manipulate control states
            oViewModel = new JSONModel({
                headerTitle: headerTitle,
                queryMode: "", //queryMode,
                tableBusyDelay: 0,
                salesOrders: null
            });
            this.getRouter().getRoute("SalesOrderList").attachPatternMatched(this._onObjectMatched, this);
            this.setModel(oViewModel, "salesOrderListView");
            // Make sure, busy indication is showing immediately so there is no
            // break after the busy indication for loading the view's meta data is
            // ended (see promise 'oWhenMetadataIsLoaded' in AppController)
            oTable.attachEventOnce("updateFinished", function () {
                // Restore original busy indicator delay for salesOrderList's table
                oViewModel.setProperty("/tableBusyDelay", iOriginalBusyDelay);
            });
            // Add the page to the flp routing history

        },
        _onObjectMatched: function (oEvent) {
            var oViewModel = this.getModel("salesOrderListView");
            var oTable = this.getView().byId("tableSalesOrders");
            var headerTitle, oResourceBundle = this.getResourceBundle();
            var queryMode = oEvent.getParameter("arguments").queryMode;
            switch (queryMode) {
            case "P":
                headerTitle = oResourceBundle.getText("salesOrderListViewTitleP");
                break;
            case "H":
                headerTitle = oResourceBundle.getText("salesOrderListViewTitleH");
                break;
            }
            oViewModel.setProperty("/headerTitle", headerTitle);
            this.addHistoryEntry({
                title: headerTitle,
                icon: "sap-icon://table-view",
                intent: "#PortalPollux-display&/SalesOrderList/" + queryMode
            }, true);
            var salesOrders = oViewModel.getProperty("/salesOrders");
            if (!salesOrders) {
                var odata = new sap.ui.model.odata.v2.ODataModel("/sap/opu/odata/sap/ZPOLLUX_SRV/");
                odata.read("/SalesOrderSet", {
                    success: function (oData, response) {
                        oViewModel.setData({
                            salesOrders: oData
                        }, true);
                    }
                });
            }
        },
        /*
         *@memberOf riders.polux.controller.SalesOrderList
         */
        onGoBack: function (oEvent) {
            //This code was generated by the layout editor.
            var oHistory = History.getInstance();
            var sPreviousHash = oHistory.getPreviousHash();
            // Go one screen back if you find a Hash
            if (sPreviousHash !== undefined) {
                window.history.go(-1);
            }
            // If you do not find a correct Hash, go to the Source screen using default router;
            else {
                var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
                oRouter.navTo("TargetLaunchpad", true);
            }
        },
        onPressCustomer: function (oEvent) {
            // The source is the list item that got pressed - custom
            this._showObjectCustomer(oEvent.getSource());
        },
        onPressVendor: function (oEvent) {
            // The source is the list item that got pressed - custom
            this._showObjectVendor(oEvent.getSource());
        },
        onPressSalesOrder: function (oEvent) {
            // The source is the list item that got pressed - custom
            this._showObjectSalesOrder(oEvent.getSource());
        },
        _showObjectCustomer: function (oItem) {
            this.getRouter().navTo("customer", {
                objectId: oItem.getBindingContext().getProperty("Kunnr")
            });
        },
        _showObjectVendor: function (oItem) {
            this.getRouter().navTo("vendor", {
                objectId: oItem.getBindingContext().getProperty("Pernr")
            });
        },
        _showObjectSalesOrder: function (oItem) {
            this.getRouter().navTo("RouteSalesOrder", {
                objectId: oItem.getBindingContext().getProperty("Vbeln")
            });
        }

    });
});

I'm fighting with this for two days and I can figure out where is my error. Can somebody help me, please? Best Regards and Thank you in advance

2

2 Answers

0
votes

From my experience using a JSONModel as solution will introduce other problems: - you only filter the datasets you fetched. But its likely you don't load them all - no automatic loading indication, no error handling while loading - complicated coding for operations on loaded datasets

My solution would be to grab the table binding and apply filters in the controller. However this can not be done in the init() function, since no table binding is set up. I usually use a navigation event that may carries a query parameter from the url that must be applied to the filters as well.

onInit: function() {
   ...
   this.getRouter().getRoute("master").attachPatternMatched(this._onMasterMatched, this);
   ...
}

_onMasterMatched: function() {
   var oList = this.byId("myTable");
   oList.getBinding("items").filter(new Filter(...)); 
}

0
votes
  1. You bound your items property to the path salesOrderListView>/salesOrders, so you are using named model with the name salesOrderListView. At the same time your field binding path looks like Customer/Name1 and it actually point to an unnamed model. In your case it has to be like salesOrderListView>Customer/Name1
  2. When you call odata.read you directly set the JSON model data by this:

oViewModel.setData({ salesOrders: oData }, true);

but if you look at oData variable during debugging you will see that most probably it is not an array, it's an object with structure:

{ d: { results: [.....] } }

So, I would try to assign data to the model this way:

oViewModel.setData({
   salesOrders: oData.d.results
}, true);