0
votes

I have an application which is working fine but has a slight problem, oData in certain cases are not ready when the first view is loaded. The app uses 2 data models, both of them declared in manifest.json, one anonymous for the main work and another one named "f4" for handling of some entities used in certain formatters and dropdowns. Data for the latter model are getting loaded via a series of read operations in the init function of the root view. Leaving aside the issue mentioned in the beginning, everything else works.

Thanks to some expert advice here, found the cause of my problem. Router gets initialized before loading of data, so I decided to move the read ops from the root view to component.js.

Here comes the problem. Model is known to the app but seems to be empty from data. I know that data are getting loaded because I debugged the application and observed the app passing from all the read success functions before successfully initializing the router. Read in another post that doing this in onInit isn't the best possible practice, so I moved again functionality from the onInit to onAfterRendering function as advised but results are still the same, no data.

So the question is: How can I access an oData model, get the required entries and made them known to the app BEFORE router initialization?

Component.js

    sap.ui.define([
    "sap/ui/core/UIComponent",
    "sap/ui/Device",
    "kristal/apps/agreements/model/models",
    "kristal/apps/agreements/controller/ErrorHandler"
], function (UIComponent, Device, models, ErrorHandler) {
    "use strict";
    // Promise vars
    var oModelTypeDataDeferred = jQuery.Deferred();
    var oModelStatusDataDeferred = jQuery.Deferred();
    var oModelActionTypeDataDeferred = jQuery.Deferred();
    var oModelRoleDataDeferred = jQuery.Deferred();
    var oModelRefDataDeferred = jQuery.Deferred();
    var oModelExtOrgDataDeferred = jQuery.Deferred();
    var oModelInvolvementDataDeferred = jQuery.Deferred();  
    return UIComponent.extend("kristal.apps.agreements.Component", {

        metadata : {
            manifest: "json"
        },

        /**
         * The component is initialized by UI5 automatically during the startup of the app and calls the init method once.
         * In this function, the FLP and device models are set and the router is initialized.
         * @public
         * @override
         */
        init : function () {

            // call the base component's init function
            UIComponent.prototype.init.apply(this, arguments);

            // initialize the error handler with the component
            this._oErrorHandler = new ErrorHandler(this);

            // set the device model
            this.setModel(models.createDeviceModel(), "device");
            // set the FLP model
            this.setModel(models.createFLPModel(), "FLP");

            // Initialize additional data - UITGKA
            var oModel = this.getModel();       
            var sPath = "/Agreement_TypesSet";
            oModel.read(sPath, {
                success: function(oData, oResponse) {
                    oModelTypeDataDeferred.resolve();
                },
                error: function(oError) {
                    jQuery.sap.log.error("Error", oError);
                }
            }); 
            sPath = "/Agreement_StatusesSet";
            oModel.read(sPath, {
                success: function(oData, oResponse) {
                    oModelStatusDataDeferred.resolve();
                },
                error: function(oError) {
                    jQuery.sap.log.error("Error", oError);
                }
            });
            sPath = "/Action_TypesSet";
            oModel.read(sPath, {
                success: function(oData, oResponse) {
                    oModelActionTypeDataDeferred.resolve();
                },
                error: function(oError) {
                    jQuery.sap.log.error("Error", oError);
                }
            });             
            sPath = "/Role_TypesSet";
            oModel.read(sPath, {
                success: function(oData, oResponse) {
                    oModelRoleDataDeferred.resolve();
                },
                error: function(oError) {
                    jQuery.sap.log.error("Error", oError);
                }
            });     
            sPath = "/Reference_TypesSet";
            oModel.read(sPath, {
                success: function(oData, oResponse) {
                    oModelRefDataDeferred.resolve();
                },
                error: function(oError) {
                    jQuery.sap.log.error("Error", oError);
                }
            });
            sPath = "/External_OrganizationsSet";
            oModel.read(sPath, {
                success: function(oData, oResponse) {
                    oModelRefDataDeferred.resolve();
                },
                error: function(oError) {
                    jQuery.sap.log.error("Error", oError);
                }
            }); 
            sPath = "/Involvement_TypesSet";
            oModel.read(sPath, {
                success: function(oData, oResponse) {
                    oModelInvolvementDataDeferred.resolve();
                },
                error: function(oError) {
                    jQuery.sap.log.error("Error", oError);
                }
            });     

            var readyToGo = function() {
                jQuery.sap.log.error("Ready", "f4");
                this.getRouter().initialize();  
            };  
            jQuery.when(oModelTypeDataDeferred, oModelStatusDataDeferred, oModelActionTypeDataDeferred, oModelRoleDataDeferred, +
             oModelRefDataDeferred, oModelExtOrgDataDeferred, oModelInvolvementDataDeferred).done().then( jQuery.proxy(readyToGo, this) );                      
        },

        /**
         * The component is destroyed by UI5 automatically.
         * In this method, the ErrorHandler is destroyed.
         * @public
         * @override
         */
        destroy : function () {
            this._oErrorHandler.destroy();
            // call the base component's destroy function
            UIComponent.prototype.destroy.apply(this, arguments);
        },

        /**
         * This method can be called to determine whether the sapUiSizeCompact or sapUiSizeCozy
         * design mode class should be set, which influences the size appearance of some controls.
         * @public
         * @return {string} css class, either 'sapUiSizeCompact' or 'sapUiSizeCozy' - or an empty string if no css class should be set
         */
        getContentDensityClass : function() {
            if (this._sContentDensityClass === undefined) {
                // check whether FLP has already set the content density class; do nothing in this case
                if (jQuery(document.body).hasClass("sapUiSizeCozy") || jQuery(document.body).hasClass("sapUiSizeCompact")) {
                    this._sContentDensityClass = "";
                } else if (!Device.support.touch) { // apply "compact" mode if touch is not supported
                    this._sContentDensityClass = "sapUiSizeCompact";
                } else {
                    // "cozy" in case of touch support; default for most sap.m controls, but needed for desktop-first controls like sap.ui.table.Table
                    this._sContentDensityClass = "sapUiSizeCozy";
                }
            }
            return this._sContentDensityClass;
        }

    });

}

);

Root view controller (app.controller.js)

    sap.ui.define([
    "kristal/apps/agreements/controller/BaseController",
    "sap/ui/model/json/JSONModel"
], function (BaseController, JSONModel) {
    "use strict";

    return BaseController.extend("kristal.apps.agreements.controller.App", {

        onInit : function () {

            var oViewModel,
                fnSetAppNotBusy,
                iOriginalBusyDelay = this.getView().getBusyIndicatorDelay();

            oViewModel = new JSONModel({
                busy : true,
                delay : 0
            });
            this.setModel(oViewModel, "appView");

            fnSetAppNotBusy = function() {
                oViewModel.setProperty("/busy", false);
                oViewModel.setProperty("/delay", iOriginalBusyDelay);
            };

            this.getOwnerComponent().getModel().metadataLoaded().
                then(fnSetAppNotBusy);

                // apply content density mode to root view
            this.getView().addStyleClass(this.getOwnerComponent().getContentDensityClass());                

        },
        onBeforeRendering : function() {

        }
    });

}

);

Worklist Controller (Worklist.controller.js)

    sap.ui.define([
    "kristal/apps/agreements/controller/BaseController",
    "sap/ui/model/json/JSONModel",
    "sap/ui/core/routing/History",
    "kristal/apps/agreements/model/formatter",
    "sap/ui/model/Filter",
    "sap/ui/model/FilterOperator"
], function (BaseController, JSONModel, History, formatter, Filter, FilterOperator) {
    "use strict";

    return BaseController.extend("kristal.apps.agreements.controller.Worklist", {

        formatter: formatter,

        /* =========================================================== */
        /* lifecycle methods                                           */
        /* =========================================================== */

        /**
         * Called when the worklist controller is instantiated.
         * @public
         */
        onInit : function () {

            var oViewModel,
                iOriginalBusyDelay,
                oTable = this.byId("table");

            // Put down worklist 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();
            // keeps the search state
            this._oTableSearchState = [];

            // Model used to manipulate control states
            oViewModel = new JSONModel({
                worklistTableTitle : this.getResourceBundle().getText("worklistTableTitle"),
                saveAsTileTitle: this.getResourceBundle().getText("worklistViewTitle"),
                shareOnJamTitle: this.getResourceBundle().getText("worklistViewTitle"),
                shareSendEmailSubject: this.getResourceBundle().getText("shareSendEmailWorklistSubject"),
                shareSendEmailMessage: this.getResourceBundle().getText("shareSendEmailWorklistMessage", [location.href]),
                tableNoDataText : this.getResourceBundle().getText("tableNoDataText"),
                tableBusyDelay : 0
            });
            this.setModel(oViewModel, "worklistView");

            // 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 worklist's table
                oViewModel.setProperty("/tableBusyDelay", iOriginalBusyDelay);
            });

            // Initialize column sorters
            this._IDSorter = new sap.ui.model.Sorter("AgrId", false);   
            this._TypeSorter = new sap.ui.model.Sorter("AgrTypeid", false, function(oContext) {
                var target = oContext.getProperty("ct>AgrTypeid");

                if (target.length === 0) {
                    return {
                        key: "",
                        text: "No Category"
                    };
                } else {
                    return {
                        key: formatter.textAgreementType(target),
                        text: formatter.textAgreementType(target)
                    };
                } 
            }); 

            this._PriceSorter = new sap.ui.model.Sorter("Price", false);
            this._StatusSorter = new sap.ui.model.Sorter("AgrStatid", false, function(oContext) {
                var target = oContext.getProperty("ct>AgrStatid");

                if (target.length === 0) {
                    return {
                        key: "",
                        text: "No Category"
                    };
                } else {
                    return {
                        key: formatter.textStatus(target),
                        text: formatter.textStatus(target)
                    };
                } 
            }); 
            // filter bar stuff
            this.oFilterBar = null;
            var sViewId = this.getView().getId();

            this.oFilterBar = sap.ui.getCore().byId(sViewId + "--filterBar");

            this.oFilterBar.registerFetchData(this.fFetchData);
            this.oFilterBar.registerApplyData(this.fApplyData);
            this.oFilterBar.registerGetFiltersWithValues(this.fGetFiltersWithValues);

            this.fVariantStub();

            //this.onToggleSearchField();

            this.oFilterBar.fireInitialise();

            this._sHeader = this.oFilterBar.getHeader();
        },

        /* =========================================================== */
        /* event handlers                                              */
        /* =========================================================== */

        /**
         * Triggered by the table's 'updateFinished' event: after new table
         * data is available, this handler method updates the table counter.
         * This should only happen if the update was successful, which is
         * why this handler is attached to 'updateFinished' and not to the
         * table's list binding's 'dataReceived' method.
         * @param {sap.ui.base.Event} oEvent the update finished event
         * @public
         */
        onUpdateFinished : function (oEvent) {
            // update the worklist's object counter after the table update
            var sTitle,
                oTable = oEvent.getSource(),
                iTotalItems = oEvent.getParameter("total");
            // only update the counter if the length is final and
            // the table is not empty
            if (iTotalItems && oTable.getBinding("items").isLengthFinal()) {
                sTitle = this.getResourceBundle().getText("worklistTableTitleCount", [iTotalItems]);
            } else {
                sTitle = this.getResourceBundle().getText("worklistTableTitle");
            }
            this.getModel("worklistView").setProperty("/worklistTableTitle", sTitle);
        },

        /**
         * Event handler when a table item gets pressed
         * @param {sap.ui.base.Event} oEvent the table selectionChange event
         * @public
         */
        onPress : function (oEvent) {
            // The source is the list item that got pressed
            this._showObject(oEvent.getSource());
        },


        /**
         * Event handler for navigating back.
         * It there is a history entry or an previous app-to-app navigation we go one step back in the browser history
         * If not, it will navigate to the shell home
         * @public
         */
        onNavBack : function() {
            var sPreviousHash = History.getInstance().getPreviousHash(),
                oCrossAppNavigator = sap.ushell.Container.getService("CrossApplicationNavigation");

            if (sPreviousHash !== undefined || !oCrossAppNavigator.isInitialNavigation()) {
                history.go(-1);
            } else {
                oCrossAppNavigator.toExternal({
                    target: {shellHash: "#Shell-home"}
                });
            }
        },

        /**
         * Event handler when the share in JAM button has been clicked
         * @public
         */
        onShareInJamPress : function () {
            var oViewModel = this.getModel("worklistView"),
                oShareDialog = sap.ui.getCore().createComponent({
                    name: "sap.collaboration.components.fiori.sharing.dialog",
                    settings: {
                        object:{
                            id: location.href,
                            share: oViewModel.getProperty("/shareOnJamTitle")
                        }
                    }
                });
            oShareDialog.open();
        },

        onSearch : function (oEvent) {
        /*  if (oEvent.getParameters().refreshButtonPressed) {
                // Search field's 'refresh' button has been pressed.
                // This is visible if you select any master list item.
                // In this case no new search is triggered, we only
                // refresh the list binding.
                this.onRefresh();
            } else { */
                var oFilter;
                var oTableSearchState = [];
                //var sQuery = oEvent.getParameter("query");
                var sSearchKey = this.getView().byId("application-agreements-display-component---worklist--searchField").getValue();
                var sStatusKey = this.getView().byId("application-agreements-display-component---worklist--cbStatus").getSelectedKey();
                var sTypeKey = this.getView().byId("application-agreements-display-component---worklist--cbType").getSelectedKey();
                //if (sQuery && sQuery.length > 0) {
                    //oTableSearchState = [new Filter("AgrId", FilterOperator.Contains, sQuery)];
                    //var oFilter = new Filter("AgrId", FilterOperator.Contains, sQuery);
                if (sSearchKey !== "") {
                    oFilter = new Filter("AgrId", FilterOperator.Contains, sSearchKey);
                    oTableSearchState.push(oFilter);                        
                }
                if (sStatusKey !== "") {
                    oFilter = new Filter("AgrStatid", FilterOperator.EQ, sStatusKey);
                    oTableSearchState.push(oFilter);
                }
                if (sTypeKey !== "") {
                    oFilter = new Filter("AgrTypeid", FilterOperator.EQ, sTypeKey);
                    oTableSearchState.push(oFilter);
                }
                //}
                this._applySearch(oTableSearchState);
            //}

        },

        /**
         * Event handler for refresh event. Keeps filter, sort
         * and group settings and refreshes the list binding.
         * @public
         */
        onRefresh : function() {
            var oTable = this.byId("table");
            oTable.getBinding("items").refresh();
        },
        // Custom sorters
        onSortID : function(){
            this._IDSorter.bDescending = !this._IDSorter.bDescending;
            this.byId("table").getBinding("items").sort(this._IDSorter);
        },  
        onSortType : function(){
            this._TypeSorter.bDescending = !this._TypeSorter.bDescending;
            this.byId("table").getBinding("items").sort(this._TypeSorter);
        },      
        /*onSortComment : function(){
            this._CommentSorter.bDescending = !this._CommentSorter.bDescending;
            this.byId("table").getBinding("items").sort(this._CommentSorter);
        },*/        
        onSortPrice : function(){
            this._PriceSorter.bDescending = !this._PriceSorter.bDescending;
            this.byId("table").getBinding("items").sort(this._PriceSorter);
        },          
        onSortStatus : function(){
            this._StatusSorter.bDescending = !this._StatusSorter.bDescending;
            this.byId("table").getBinding("items").sort(this._StatusSorter);
        },                  
        /* =========================================================== */
        /* internal methods                                            */
        /* =========================================================== */

        /**
         * Shows the selected item on the object page
         * On phones a additional history entry is created
         * @param {sap.m.ObjectListItem} oItem selected Item
         * @private
         */
        _showObject : function (oItem) {
            this.getRouter().navTo("object", {
                objectId: oItem.getBindingContext().getProperty("AgrId")
            });
        },

        /**
         * Internal helper method to apply both filter and search state together on the list binding
         * @param {object} oTableSearchState an array of filters for the search
         * @private
         */
        _applySearch: function(oTableSearchState) {
            var oTable = this.byId("table"),
                oViewModel = this.getModel("worklistView");
            oTable.getBinding("items").filter(oTableSearchState, "Application");
            // changes the noDataText of the list in case there are no filter results
            if (oTableSearchState.length !== 0) {
                oViewModel.setProperty("/tableNoDataText", this.getResourceBundle().getText("worklistNoDataWithSearchText"));
            }
        },
        // Filter bar stuff
        onToggleSearchField: function(oEvent) {

            var oSearchField = this.oFilterBar.getBasicSearch();
            if (!oSearchField) {
                var oBasicSearch = new sap.m.SearchField({
                    showSearchButton: false
                });
            } else {
                oSearchField = null;
            }

            this.oFilterBar.setBasicSearch(oBasicSearch);

            oBasicSearch.attachBrowserEvent("keyup", jQuery.proxy(function(e) {
                if (e.which === 13) {
                    this.onSearch();
                }
            }, this));
        },
        onToggleShowFilters: function(oEvent) {

            var bFlag = this.oFilterBar.getShowFilterConfiguration();
            this.oFilterBar.setShowFilterConfiguration(!bFlag);
        },

        onToggleHeader: function(oEvent) {

            var sHeader = "";
            if (this.oFilterBar.getHeader() !== this._sHeader) {
                sHeader = this._oHeader;
            }

            this.oFilterBar.setHeader(sHeader);

        },
        onChange: function(oEvent) {
            this.oFilterBar.fireFilterChange(oEvent);
        },
        onClear: function(oEvent) {
            var oItems = this.oFilterBar.getAllFilterItems(true);
            for (var i = 0; i < oItems.length; i++) {
                var oControl = this.oFilterBar.determineControlByFilterItem(oItems[i]);
                if (oControl) {
                    var sType = oControl.getMetadata().getName();
                    if (sType === "sap.m.ComboBox") {
                        oControl.setSelectedKey("");
                    } else {
                        oControl.setValue("");
                    }
                }
            }
        },
        _showToast: function(sMessage) {
            jQuery.sap.require("sap.m.MessageToast");
            sap.m.MessageToast.show(sMessage);
        },
        onCancel: function(oEvent) {
            this._showToast("cancel triggered");
        },
        onReset: function(oEvent) {
            this._showToast("reset triggered");
        },
        /*onSearch: function(oEvent) {
            this._showToast("search triggered");
        },*/
        onFiltersDialogClosed: function(oEvent) {
            this._showToast("filtersDialogClosed triggered");
        },
        fFetchData: function() {

            var sGroupName;
            var oJsonParam;
            var oJsonData = [];

            var oItems = this.getAllFilterItems(true);
            for (var i = 0; i < oItems.length; i++) {
                oJsonParam = {};
                sGroupName = null;
                if (oItems[i].getGroupName) {
                    sGroupName = oItems[i].getGroupName();
                    oJsonParam.group_name = sGroupName;
                }

                oJsonParam.name = oItems[i].getName();

                var oControl = this.determineControlByFilterItem(oItems[i]);
                if (oControl) {
                    oJsonParam.value = oControl.getValue();
                    oJsonData.push(oJsonParam);
                }
            }

            return oJsonData;
        },
        fApplyData: function(oJsonData) {

            var sGroupName;

            for (var i = 0; i < oJsonData.length; i++) {

                sGroupName = null;

                if (oJsonData[i].group_name) {
                    sGroupName = oJsonData[i].group_name;
                }

                var oControl = this.determineControlByName(oJsonData[i].name, sGroupName);
                if (oControl) {
                    oControl.setValue(oJsonData[i].value);
                }
            }
        },
        fGetFiltersWithValues: function() {
            var i;
            var oControl;
            var aFilters = this.getFilterGroupItems();

            var aFiltersWithValue = [];

            for (i = 0; i < aFilters.length; i++) {
                oControl = this.determineControlByFilterItem(aFilters[i]);
                if (oControl && oControl.getValue && oControl.getValue()) {
                    aFiltersWithValue.push(aFilters[i]);
                }
            }

            return aFiltersWithValue;
        },
        fVariantStub: function() {
            var oVM = this.oFilterBar._oVariantManagement;
            oVM.initialise = function() {
                this.fireEvent("initialise");
                this._setStandardVariant();

                this._setSelectedVariant();
            };

            var nKey = 0;
            var mMap = {};
            var sCurrentVariantKey = null;
            oVM._oVariantSet = {

                getVariant: function(sKey) {
                    return mMap[sKey];
                },
                addVariant: function(sName) {
                    var sKey = "" + nKey++;

                    var oVariant = {
                        key: sKey,
                        name: sName,
                        getItemValue: function(s) {
                            return this[s];
                        },
                        setItemValue: function(s, oObj) {
                            this[s] = oObj;
                        },
                        getVariantKey: function() {
                            return this.key;
                        }
                    };
                    mMap[sKey] = oVariant;

                    return oVariant;
                },
                setCurrentVariantKey: function(sKey) {
                    sCurrentVariantKey = sKey;
                },
                getCurrentVariantKey: function() {
                    return sCurrentVariantKey;
                },
                delVariant: function(sKey) {
                    if (mMap[sKey]) {
                        delete mMap[sKey];
                    }
                }
            };
        }           
    });
}

);

Worklist.view.xml

    <mvc:View
controllerName="kristal.apps.agreements.controller.Worklist"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
xmlns:semantic="sap.m.semantic"
xmlns:fb="sap.ui.comp.filterbar"
xmlns:core="sap.ui.core"
xmlns:footerbar="sap.ushell.ui.footerbar">

<semantic:FullscreenPage
    id="page"
    navButtonPress="onNavBack"
    showNavButton="true"
    title="{i18n>worklistViewTitle}">
    <semantic:content>
        <fb:FilterBar id="filterBar" header="{i18n>worklistListFilters}" enableBasicSearch="true" 
                        reset="onReset" search="onSearch" clear="onClear" cancel="onCancel" 
                        filtersDialogClosed = "onFiltersDialogClosed"
                        showRestoreButton="true" showClearButton="true" showCancelButton="true">            
            <fb:filterItems>
                <!--fb:FilterItem name="A" label="Delivery Date">
                    <fb:control>
                        <DatePicker change="onChange"/>
                    </fb:control>               
                </fb:FilterItem-->
                <fb:FilterItem name="sSearch" label="Search Agreement">
                    <fb:control>
                        <Input
                            id="searchField"
                            tooltip="{i18n>worklistSearchTooltip}"
                            width="auto"/>
                    </fb:control>
                </fb:FilterItem>
                <fb:FilterItem name="A" label="{i18n>tableTypeColumnTitle}" labelTooltip="Agreement Types">
                    <fb:control>
                        <ComboBox id="cbType" items="{
                                              path: 'f4>/Agreement_TypesSet',
                                              sorter: { path: 'AgrTypeid' }
                                          }">
                            <items> 
                                <core:Item key="{f4>AgrTypeid}" text="{f4>AgrTypetxt}"/>
                            </items> 
                        </ComboBox>                                 
                    </fb:control>               
                </fb:FilterItem>    
                <fb:FilterItem name="B" label="{i18n>tableStatusColumnTitle}" labelTooltip="Statuses">
                    <fb:control>
                        <ComboBox id="cbStatus" items="{
                                              path: 'f4>/Agreement_StatusesSet',
                                              sorter: { path: 'AgrStatid' }
                                          }">
                            <items> 
                                <core:Item key="{f4>AgrStatid}" text="{f4>AgrStattxt}"/>
                            </items> 
                        </ComboBox>                                 
                    </fb:control>               
                </fb:FilterItem>                    
            </fb:filterItems>
        </fb:FilterBar>             

        <Table
            id="table"
            width="auto"
            class="sapUiResponsiveMargin"
            items="{
                path: '/AgreementsSet',
                sorter: { path: 'AgrId' }
            }"
            noDataText="{worklistView>/tableNoDataText}"
            busyIndicatorDelay="{worklistView>/tableBusyDelay}"
            growing="true"
            growingScrollToLoad="true"
            updateFinished="onUpdateFinished">

            <headerToolbar>
                <Toolbar>
                    <Title id="tableHeader" text="{worklistView>/worklistTableTitle}"/>
                    <ToolbarSpacer />
                    <!--SearchField
                        id="searchField"
                        tooltip="{i18n>worklistSearchTooltip}"
                        search="onSearch"
                        width="auto">
                    </SearchField-->
                </Toolbar>
            </headerToolbar>
            <columns>
                <Column id="nameColumn">
                    <header>
                        <Toolbar>
                            <Text text="{i18n>tableNameColumnTitle}" id="nameColumnTitle"/>
                            <Button
                                icon="sap-icon://sort"
                                press="onSortID" />
                        </Toolbar>
                    </header>
                </Column>
                <Column id="typeColumn">
                    <header>
                        <Toolbar>                       
                            <Text text="{i18n>tableTypeColumnTitle}" id="nameTypeTitle"/>
                            <Button
                                icon="sap-icon://sort"
                                press="onSortType" />
                        </Toolbar>
                    </header>                               
                </Column>                   
                <Column id="commentColumn">
                    <header>
                        <Toolbar>                       
                            <Text text="{i18n>tableCommentColumnTitle}" id="nameCommentTitle"/>
                            <!--Button
                                icon="sap-icon://sort"
                                press="onSortComment" /-->
                        </Toolbar>
                    </header>                                   
                </Column>
                <Column id="unitNumberColumn" hAlign="Right">
                    <header align="Right">
                        <Toolbar>                           
                            <Text text="{i18n>tableUnitNumberColumnTitle}" id="unitNumberColumnTitle"/>
                            <Button
                                icon="sap-icon://sort"
                                press="onSortPrice" />
                        </Toolbar>
                    </header>                               
                </Column>
                <Column id="statusColumn" hAlign="Right">
                    <header align="Right">
                        <Toolbar>                           
                            <Text text="{i18n>tableStatusColumnTitle}" id="nameStatusTitle"/>
                            <Button
                                icon="sap-icon://sort"
                                press="onSortStatus" />
                        </Toolbar>
                    </header>                                   
                </Column>                   
            </columns>
            <items>
                <ColumnListItem
                    type="Navigation"
                    press="onPress">
                    <cells>
                        <ObjectIdentifier
                            title="{AgrId}"
                            text="{Shorttitle}">
                        </ObjectIdentifier>
                        <Text text="{
                                path: 'AgrTypeid',
                                formatter: '.formatter.textAgreementType'
                              }"/>  
                        <Text text="{AgrComment}"/>     
                        <ObjectNumber
                            number="{
                                path: 'Price',
                                formatter: '.formatter.numberUnit'
                            }"
                            unit="{Curr}"/>
                        <ObjectStatus 
                            text="{
                                path: 'AgrStatid',
                                formatter: '.formatter.textStatus'
                            }"
                            state="{
                                path: 'AgrStatid',
                                formatter: '.formatter.stateStatus'
                            }"                              
                        />
                    </cells>
                </ColumnListItem>
            </items>
        </Table>
    </semantic:content>

    <semantic:sendEmailAction>
        <semantic:SendEmailAction id="shareEmail" press="onShareEmailPress"/>
    </semantic:sendEmailAction>

    <semantic:shareInJamAction>
        <semantic:ShareInJamAction id="shareInJam" visible="{FLP>/isShareInJamActive}" press="onShareInJamPress"/>
    </semantic:shareInJamAction>

    <semantic:saveAsTileAction>
        <footerbar:AddBookmarkButton id ="shareTile" title="{worklistView>/saveAsTileTitle}" />
    </semantic:saveAsTileAction>

</semantic:FullscreenPage>

2
Please, avoid setting models on the Core if you're working with Components. This answer might help to understand model propagation: stackoverflow.com/a/42251431Boghyon Hoffmann
Also try to replace sap.ui.model.odata.ODataModel with the equivalent v2.ODataModel. The former model has been deprecated for a long time.Boghyon Hoffmann
@BoghyonHoffmann: easy stuff first: aware of the V2 model, copied the wrong statement in my code (lazy, next time better write it on hand)Greg
@BoghyonHoffmann: Model propagation: if I got this right, since this is a component based app, the only way to make the model defined in manifest visible to component.js is by wrapping the component within a component container and setting the parameter propagateModel to true. If the above sentence is true, I suppose that I should declare the container in the root view. Could find any sample, so I did that directly after the opening view tag, and app fell on a loop ending to "maximum stack exceeded" exception while searching for the language files (view code attached above)...any ideas?Greg
"I experienced the problem of being unable to access the model declared in manifest.json" - Can you explain it a bit more? How and where exactly did you try to access the model? As explained in the answer I linked here, models declared in app descriptor (manifest.json) can be accessed from Component.js (via this.getModel) as well as from Controller (via this.getOwnerComponent().getModel).Boghyon Hoffmann

2 Answers

0
votes

As well as the earlier responses let me add that I usually use the metadataLoaded promise to ensure the model is fully instantiated.

        init : function () {
            ...
            sap.ui.getCore().getModel()..metadataLoaded().then(this._onMetadataLoaded.bind(this));
        },
        _onMetadataLoaded: function() {
            ...
        }
0
votes

The question has been revised in such a level that doesn't reflect the initial problem, which was mistaken use of the additional named model in component.js. The way question looks now, the problem is just the var oModel = this.getModel(); statement in component.js where the model name is missing.

Thank you @BoghyonHoffmann not only for providing the solution but for being so patient in the last days and guiding me all along as well. It's not only about the thing working but also about the lots of mistaken perceptions that were clarified here, regarding the use of the data model, cheers!