Currently Being Moderated

My previous blog provided an overview Sencha frameworks and tools to build mobile apps. In this post we’ll start coding an example mobile app that connects to SAP Gateway using OData. We will be using the SAP Gateway demo system

 

 

Hello world!

So let's get started with the basics: an HTML page to load the Sencha Touch library and the app. The easiest way to get started with Sencha Touch is using the hosted library on cdn.sencha.io.

 

Create the following app.html file that includes Sencha Touch javascript library and stylesheet:

 

<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
<!-- include the Sencha Touch stylesheet -->
<link rel="stylesheet" 
        href="http://cdn.sencha.io/touch/sencha-touch-2.1.0/resources/css/sencha-touch.css"/>
<!-- include the Sencha Touch library -->    
<script src="http://cdn.sencha.io/touch/sencha-touch-2.1.0/sencha-touch-all-debug.js"></script>
    
<!-- include your app code -->
<script src="app.js"></script>  
</head>
<body>
</body>
</html>

 

 

 

Our application code is in app.js:

 

// Ext.application is entry point for a Sencha Touch application
Ext.application({
  // launch function will be called when all code is loaded and DOM is ready
  launch: function () {
    // create and display a messagebox
    Ext.Msg.alert('Hello SAP SCN', 'Sencha Touch is ready action!');
  }
});

 

 

Put these files on a local webserver and point your Chrome browser at app.html:

helloword.png

 

We've got our basic app running! We're ready to take the next step.

 

 

Creating a list view

 

This step will introduce you to the class system that is at the heart of Sencha Touch (from now on abbreviated to ST). It provides inheritance, namespacing, mixins, dependency definitions and more.

 

In ST you typically create building blocks by defining classes that extend (i.e. inherit from) the classes offered by ST. This is shown in the next example. We define a new CarrierList class by extending the built-in Ext.dataview.List and create an instance of this class in the launch function (the DOM needs to be ready before we can insert a UI component).

 

// With Ext.define you can define a class
Ext.define('App.view.CarrierList', {
    // we want to inherit from the built-in Ext.dataview.List 
    extend: 'Ext.dataview.List',
    config: {
        // this component should fill the whole screen (viewport)
        fullscreen: true,
        // we'll provide some inline data
        data: [
            { code: 'AB', name: 'Air Berlin' },
            { code: 'BA', name: 'British Airways' },
            { code: 'DE', name: 'Delta Airlines' }
        ],
        // define a template that is used to render each data record:
        itemTpl: '{code} - {name}',
        // define a titlebar at the top as a child item of the List container
        items: [{
            xtype: 'titlebar',
            docked: 'top',
            title: 'Carriers'
        }]
    }
});
Ext.application({
    launch: function () {
        // Ext.create will create an instance of a class
        Ext.create('App.view.CarrierList');
    }
});

 

 

 

If you put this code in your app.js, you’ll see:

CarrierList.png

 

 

A couple of thing to note here:

 

  • Ext.define() defines a class, Ext.create() creates an instance of a class
  • The titlebar is a child item of the CarrierList. The titlebar is an example of a UI component. Components that can contain other components (i.e. child items) are called Containers.
  • The titlebar is not instantiated immediately with Ext.create(). Instead it is configured using an xtype, which is a short alias for a UI component class, e.g.
    ‘titlebar’ refers to class Ext.TitleBar. ST will defer instantiation until the a CarrierList is created. This is called lazy instantiation.

 

 

Fetching data from SAP Gateway

 

In the previous example we used inline data. Now let’s get some data from SAP Gateway using OData.

 

We will use the TravelAgency collection from the Flight sample database on the SAP Gateway demo system and display the Travel Agencies in a List.

 

The screenshot below shows a part of the OData feed for the TravelAgency collection:

OData.png

 

To access this SAP data from Sencha Touch, we first define a TravelAgency model.

 

// define the TravelAgency model
Ext.define('App.model.TravelAgency', {
    extend: 'Ext.data.Model',
    config: {
        // list the fields, the default type is string
        fields: [
          { name: "TravelAgencyID" },
          { name: "Name" },
          { name: "Street" },
          { name: "POBox" },
          { name: "PostalCode" },
          { name: "City" },
          { name: "Country" },
          { name: "Region" },
          { name: "TelephoneNumber" },
          { name: "URL" },
          { name: "LanguageCode" },
          { name: "LocalCurrencyCode" }
        ],
        proxy: {
            type: 'odata',
            url: 'http://gw.esworkplace.sap.com/sap/opu/odata/IWBEP/RMTSAMPLEFLIGHT_2/'+
                  'TravelAgencyCollection',
            withCredentials: true,
            username: 'GW@ESW',
            password: 'ESW4GW'
        }
    }
});

 

This Model defines the fields and also the proxy type to use. In Sencha Touch, a data proxy is the bridge between data on the server and data in the application. The proxy takes care of preparing requests (e.g. parameters, and payload) and transforming server responses into Model instances.

 

As a result of the partnership with SAP, Sencha made available the SAP OData connector, which contains a data proxy to communicate with SAP Gateway and other SAP OData sources (e.g. SAP HANA). Please download the SAP connector and include a script link to the OData.js file after the ST library and before your app.js in your html page.

 

 

For a list we actually want to fetch multiple records in one go. So we'll define a Store, which can hold a collection of model instances.

 

// define a store to load a collection TravelAgency records
Ext.define('App.store.TravelAgencies', {
    extend: 'Ext.data.Store',
    config: {
        model: 'App.model.TravelAgency',
        // perform client-side sorting on field Name
        sorters: 'Name',
        // configure grouping
        grouper: {
            // group by the first letter of Name field
            groupFn: function (record) {
                return record.get('Name')[0];
            }
        }
    }
});

 

As you can see the TravelAgencies Store is configured wth the TravelAgency Model. This way ST knows which proxy and fields to use when trying to load server data.

 

Please note that I included a grouper function. It returns the first letter of the Travel Ageny's name and is used to build a grouped list, which we will define next

 

The List view lists the names of the agencies and groups them by first letter.

// define a List to display Travel Agencies
Ext.define('App.view.TravelAgencyList', {
    extend: 'Ext.dataview.List',
    config: {
        // we want a grouped list
        grouped: true,
        // just display the name of each TravelAgency
        itemTpl: '{Name}'
    }
});

 

Finally, we use our building blocks to launch our application:

 

Ext.application({
    launch: function () {
        // create a store. 
        var store = Ext.create('App.store.TravelAgencies');
       // load the records from the SAP Gateway
       store.load();
        // create a list view and bind it to the store
        Ext.create('App.view.TravelAgencyList', {
            fullscreen: true,
            store: store
        });
    }
});

 

 

Now, fire up your Chrome browser with the “disable-web-security” command line. This will suppress the Same Origin Policy which normally doesn’t allow you to do XHR request across domains:

 

ChromeDisableWebSecurity.png

 

Now you can view app.html in Chrome, showing the TravelAgencies fetched from SAP Gateway:

TravelAgencyList.png

 

Time to wrap up: in this post we have seen models and views. In the part 3 we're going to add a controller to coordinate between models and views. We will also cover how ST can create, update and delete data on SAP Gateway data.

 

Thanks for reading!

Comments

Actions

Filter Blog

By author:
By date:
By tag: