1
votes

Expected Output
On clicking a row of the table details page should show the details of that row

Issue

  • Data binding not working.
    • In details view the controls are not showing the data bind to it.
    • In details view controller, if I print the context(which i am getting through getSelectedContext() on table)in console it is showing the data, but in view the controls are not showing the data bind to it

index.html

<!DOCTYPE HTML>
    <html>
        <head>
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
            <script src="resources/sap-ui-core.js"
                    id="sap-ui-bootstrap"
                    data-sap-ui-libs="sap.m"
                    data-sap-ui-theme="sap_bluecrystal">
            </script>
            <!-- only load the mobile lib "sap.m" and the "sap_bluecrystal" theme -->

            <script>
                //set local resources
                sap.ui.localResources("odatacruddemo");

                //create app and set the initialPage to be displayed
                var app = new sap.m.App({
                    initialPage: 'masterPage'
                });

                var masterPage = new sap.ui.view({
                    id: 'masterPage',
                    viewName: 'odatacruddemo.Master',
                    type: sap.ui.core.mvc.ViewType.JS
                });

                var detailsPage = new sap.ui.view({
                    id: 'detailsPage',
                    viewName: 'odatacruddemo.Details',
                    type: sap.ui.core.mvc.ViewType.JS
                });

                app.addPage(masterPage);
                app.addPage(detailsPage);
                app.placeAt('content');
            </script>

        </head>
        <body class="sapUiBody" role="application">
            <div id="content"></div>
        </body>
    </html>

Master.view.js

sap.ui.jsview("odatacruddemo.Master", {

    /** Specifies the Controller belonging to this View. 
    * In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
    * @memberOf odatacruddemo.Master
    */ 
    getControllerName : function() {
        return "odatacruddemo.Master";
    },

    /** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed. 
    * Since the Controller is given to this method, its event handlers can be attached right away. 
    * @memberOf odatacruddemo.Master
    */ 
    createContent : function(oController) { 
        //add columns in a  array to be added in table
        var aProductTableColumns = [
            new sap.m.Column({
                header: new sap.m.Text({
                    text: 'Person ID'
                })
            }),
            new sap.m.Column({
                header: new sap.m.Text({
                    text: 'Name'
                })
            }),
            new sap.m.Column({
                header: new sap.m.Text({
                    text: 'EmployeeID'
                })
            }),
            new sap.m.Column({
                header: new sap.m.Text({
                    text: 'HireDate'
                })
            }),
            new sap.m.Column({
                header: new sap.m.Text({
                    text: 'Salary'
                })
            }),
            new sap.m.Column({
                header: new sap.m.Text({
                    text: 'Operations'
                })
            })

        ];

        //add the data to the table using cells aggregation by using ColumnListItem
        var oTableTemplate = new sap.m.ColumnListItem({
            type: "Navigation",
            press: [oController.onListPress, oController],
            cells: [
                new sap.m.ObjectIdentifier({
                    text: '{ID}'
                }),
                new sap.m.ObjectIdentifier({
                    text: '{Name}'
                }),
                new sap.m.ObjectIdentifier({
                    text: '{EmployeeID}'
                }),
                new sap.m.ObjectIdentifier({
                    text: '{HireDate}'
                }),
                new sap.m.ObjectIdentifier({
                    text: '{Salary}',

                })

            ]
        }).addStyleClass("sapUiResponsiveMargin");

        //oTableTemplate.setType(sap.m.ListType.Active);


        //create dialog for updating/editing data
        var editPersonDetailsDialog = new sap.m.Dialog({
            id: 'editPersonDetailsDialog',
            title: 'Update Details'
        });

        //create table 
        var oProductTable = new sap.m.Table({
            id: 'oProductTable',
            columns: aProductTableColumns,
            itemPress: [oController.onListPress,oController]
        });

        //oProductTable.setMode(sap.m.ListMode.SingleSelect);
        oProductTable.setMode(sap.m.ListMode.SingleSelectMaster); 

        //bind the JSON data received from the service with Table 
        oProductTable.bindItems("/value",oTableTemplate);


        var masterPage = new sap.m.Page({
            title: "CRUD Operations on Public Odata Service",
            content: [
                oProductTable
            ]
        });

        return masterPage;
    }
});

Master.Controller.js

sap.ui.controller("odatacruddemo.Master", {

/**
* 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 odatacruddemo.Master
*/
    onInit: function() {
        var serviceURL = 'http://services.odata.org/V4/OData/OData.svc/Persons?$expand=PersonDetail'; 
        var oModel = new sap.ui.model.json.JSONModel(serviceURL);   
        oModel.attachRequestCompleted(function(oEvent){
            //bind a model to a view
            var masterView = sap.ui.getCore().byId("masterPage");
            masterView.setModel(oModel);
            //sap.ui.getCore().setModel(oModel);
        });
        //sap.ui.getCore().setModel(oModel);
    },

/**
* Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
* (NOT before the first rendering! onInit() is used for that one!).
* @memberOf odatacruddemo.Master
*/
//  onBeforeRendering: function() {
//
//  },

/**
* Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
* This hook is the same one that SAPUI5 controls get after being rendered.
* @memberOf odatacruddemo.Master
*/
//  onAfterRendering: function() {
//
//  },

/**
* Called when the Controller is destroyed. Use this one to free resources and finalize activities.
* @memberOf odatacruddemo.Master
*/
//  onExit: function() {
//
//  }
    onListPress: function(oEvent){
        console.log('List Item pressed');   
        //Get the Selected Items
        //get the  row data which has been clicked 
        var clickedItem = sap.ui.getCore().byId('oProductTable').getSelectedItems();
        var cells = clickedItem[0].getCells();

         var contexts = sap.ui.getCore().byId("oProductTable").getSelectedContexts();
         console.log('Master ctx:');
         console.log(contexts);
         var items = contexts.map(function(c) {
             return c.getObject();
             });
         console.log(items[0]);

        var detailsPage = app.getPage('detailsPage');
        detailsPage.setBindingContext(contexts,"data");

        app.to(detailsPage);
        //var detailsView = sap.ui.getCore().byId("detailsPage");
        //detailsView.getModel().setData(items[0]);
        //var oContext = oEvent.getSource().getBindingContext();
        //console.log(oEvent);
    }

});

In above code I am setting the bindingContext to detailsPage and I am able to get that context in detailsPage but in the view it not showing the data.

Below is the DetailPage Code: Details.view.js

sap.ui.jsview("odatacruddemo.Details", {

    /** Specifies the Controller belonging to this View. 
    * In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
    * @memberOf odatacruddemo.Details
    */ 
    getControllerName : function() {
        return "odatacruddemo.Details";
    },

    /** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed. 
    * Since the Controller is given to this method, its event handlers can be attached right away. 
    * @memberOf odatacruddemo.Details
    */ 
    createContent : function(oController) {
            var oObjectHeader = new sap.m.ObjectHeader({
                title: "{Name}",

                attributes:[
                    new sap.m.ObjectAttribute({
                        text: "{Name}"
                    })
                ]
            });
        var detailsPage = new sap.m.Page({
            title: "DetailsPage",
            content: [
                oObjectHeader
            ]
        });
        return detailsPage;
    }

});

Details.controller.js

sap.ui.controller("odatacruddemo.Details", {

/**
* 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 odatacruddemo.Details
*/
    onInit: function() {
        console.log('onInit() detailPage called');

    },

/**
* Similar to onAfterRendering, but this hook is invoked before the controller's View is re-rendered
* (NOT before the first rendering! onInit() is used for that one!).
* @memberOf odatacruddemo.Details
*/
    onBeforeRendering: function() {
        var  detailsPage = sap.ui.getCore().byId('detailsPage');
        var context = detailsPage.getBindingContext("data");
        console.log('ctx:=>');
        console.log(context);
        var items = context.map(function(c) {
             return c.getObject();
             });
         console.log(items[0]);

},

/**
* Called when the View has been rendered (so its HTML is part of the document). Post-rendering manipulations of the HTML could be done here.
* This hook is the same one that SAPUI5 controls get after being rendered.
* @memberOf odatacruddemo.Details
*/
//  onAfterRendering: function() {
//
//  },

/**
* Called when the Controller is destroyed. Use this one to free resources and finalize activities.
* @memberOf odatacruddemo.Details
*/
//  onExit: function() {
//
//  }

});

In the details View the controls are not showing the data bind to it.
Master Page showing the data fetched from oData service Details page, control not showing the data Please help ... Thanks in Advance...

2

2 Answers

1
votes

your tables and controls are not having any data binding at all. You have to bind the items aggregation of your table. When using JS Views take a look at this API https://sapui5.hana.ondemand.com/#/api/sap.m.ListBase/methods/bindItems of sap.m.Table.

First of all you should use XMLViews instead of JsViews.

For your binding problem take a look in the SAPUI5 developer. Take a look at this example from the developer guide and go through it.

https://sapui5.hana.ondemand.com/#/topic/97830de2d7314e93b5c1ee3878a17be9

-1
votes
sap.ui.controller("odatacruddemo.Details", {

onInit: function() {
    console.log('onInit() detailPage called');
    var oModel2 = new sap.ui.model.json.JSONModel();
    var detailsPage  = sap.ui.getCore().byId('detailsPage');
    detailsPage.setModel(oModel2);
    this.getView().addEventDelegate({
        onBeforeShow : function(evt) {
            var  detailsPage = sap.ui.getCore().byId('detailsPage');
            var context = detailsPage.getBindingContext("data");
            console.log('ctx:=>');
            console.log(context);
            //sap.ui.getCore().getModel().setData(json);


            var items = context.map(function(c) {
                 return c.getObject();
                 });
             console.log(items[0]);

             var dPage = sap.ui.getCore().byId('detailsPage');
             dPage.getModel().setData(items[0]);
         }, 
    });

},
onNavPress: function(){
 app.back();
}});