Setting up the Master View

We now need to build a list view to populate a Master list of sales orders from our service.

Create a new View

  1. Right click on the view folder
  2. Choose New > Other …
  3. Type view in the filter box. Choose view under SAPUI5 Application Development folder.

    eclipse_04_add_new_view.PNG

  4. Enter Master as the view name and choose XML development paradigm.

Create a Sales Order List

  1. Open Master.view.xml

  2. Replace file contents with this snippet:

    <mvc:View
        controllerName="odatalabclient.view.Master"
        displayBlock="true"
        xmlns:mvc="sap.ui.core.mvc"
        xmlns="sap.m">
        <Page
            id="page"
            title="Sales Orders">
        </Page>
    </mvc:View>
    

    Now we have our base sap.m.Page to add our content. You'll notice the controller name changes a bit to keep with our standard. I noticed that the 'New View' wizard does not retain a full namespace. This is something to be aware of.

  3. In the same file, add a sap.m.List to the content of our Page. Replace the Page object with the following:

    <Page
        id="page"
        title="Sales Orders">
        <content>
            <List
                id="list"
                mode="{device>/listMode}"
                items="{/SalesOrders}"
                growing="true"
                growingScrollToLoad="true">
                <items>
                    <ObjectListItem
                        type="{device>/listItemType}"
                        title="{SoId}">
                    </ObjectListItem>
                </items>
            </List>
        </content>
    </Page>
    

    You'll notice a couple things here.

    1. We are using our {device} model that we set in Component.js. See how we are accessing those helper attributes we created?
    2. We have a sap.m.List with sap.m.ObjectListItem items
    3. The items are populated from our model {/SalesOrderHeaderCollection}. We have not yet configured this piece.
  4. Change the name of our Master controller in Master.controller.js

    sap.ui.controller("odatalabclient.view.Master", {
        // ...
    

    Let's run our application now and see some of this in effect.

  5. Refresh your browser window to see our changes.

client_02_master_list.PNG

Master Controller

Now that our view is up to speed, let's finally hook up to our OData service! In the UIComponent initialization, let's add our NetWeaver Gateway service. We are adding it here, because we are only using one domain model for this demo. All of our screens will use this model.

To do that, let's add some config in our Component.js.

  1. Open Component.js, identify the config section under metadata.
  2. Add our Sales Order service:

    rootView: "odatalabclient.view.App",
    config: {
        salesOrderService: {
            url: "/ODataLabClient/proxy/http/server.com:1234/sap/opu/odata/sap/service",
            user: "TEST1",
            password: "TestUserPassword"
        }
    },
    
    1. Change server.com:1234 above to the hostname of the service you created in a previous module, or use an existing public OData source that you can find.
    2. We are using an initial path of /ODataLabClient/proxy/http/ because, inside of Eclipse's SAPUI5 Core Runtime libraries, we are provided a com.sap.ui5.proxy.SimpleProxyServlet class which will handle requesting resources that violate the Same-origin policy. Instead of worrying about CORS issues in our demo, let's just use this proxy servlet instead. SAP advises to not use this proxy class in production.
  3. Change the contents of init function of Component.js:

    init: function() {
        sap.ui.core.UIComponent.prototype.init.apply(this, arguments);
    
        var mConfig = this.getMetadata().getConfig();
    
        var oModel = new sap.ui.model.odata.ODataModel(
            mConfig.salesOrderService.url,
            true,
            mConfig.salesOrderService.user,
            mConfig.salesOrderService.password
        );
    
        this.setModel(oModel);
    
        // set device model (phone/desktop support)
        var deviceModel = new sap.ui.model.json.JSONModel({
            // ...
    

    The first line brings in our UIComponent shell so that we can access the config we added. Inside the onInit function, we bring the url into a variable and assign it into a new instance of an sap.ui.model.odata.ODataModel object. By getting the view object from our controller, we can inject our model. If your service endpoint does not require a username and password (or if you want to prompt the user for their credentials instead of an application ID), you can leave out specifying a user and password in the new ODataModel.

    If you are going to pass credentials like this, use HTTPS only! In HTTP, requests are sent over the wire like:

    http://user:password@server.com:1234/service

    So, use HTTPS!

    As a side note, you can access the UIComponent's metadata from any controller as well. Simply require the namespace and class name.

    // include this at the top of your controller
    jQuery.sap.require("odatalabclient.Component");
    
    // then, inside any function for example:
    var config = odatalabclient.Component.getMetadata().getConfig();
    var url = config.salesOrderService.url;
    
  4. Refresh your browser window to see our changes.

client_03_master_list_with_data.PNG

We are seeing our sales orders! This is great.

  1. A request is sent to our router (which we initialized in our UIComponent)
  2. The request is loaded as a masterPages aggregation of our main view (App.view.xml)
  3. The view (Master.view.xml) is loaded in.
  4. The list in our view is bound to {/SalesOrders} model property.
  5. SAPUI5 Core will make a request from our ODataModel to the service at resource /SalesOrders
    1. A call is made to the $metadata endpoint to get information about the service.
    2. We attempt to read a $count of all resources
    3. We read in some /SalesOrders records from the OData endpoint and display in our List

All of this we have configured so far. Before we can show too much detail about these items, we need a way to pass the information from this master list, through our Router, and into a separate Detail view. To do this, we need to look at assigning click events to our Master view and using our custom router.


Previous section: