Sencha Touch 2.0 MVC tutorial

coure2011 picture coure2011 · Feb 10, 2012 · Viewed 25.5k times · Source

I am very new to Sencha Touch framework, want to start with Sencha Touch 2.0 but not able to find any tutorial showing an application built using MVC Pattern and specifically in Sencha Touch version 2.0.

Answer

Grgur picture Grgur · Feb 12, 2012

This is probably one of the earliest tutorials so be patient and know that things may change by the final release sees the light of day.

For MVC you're gonna want to set your folder structure first. Something like this:

MyApp
    app
      controller
      model
      profile
      store
      view
    touch2
    app.js
    index.html

Now, let's start with a sample app.

index.html

<!DOCTYPE html>
<html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Sample App</title>

    <link rel="stylesheet" href="touch2/resources/css/sencha-touch.css" type="text/css" title="senchatouch" id="senchatouch" />
    <link rel="stylesheet" href="touch2/resources/css/android.css" type="text/css" title="android" id="android" disabled="true" />
    <link rel="stylesheet" href="touch2/resources/css/apple.css" type="text/css" title="apple" id="apple" disabled="true" />
    <link rel="stylesheet" href="touch2/resources/css/bb6.css" type="text/css" title="blackberry" id="blackberry" disabled="true" />

    <link rel="stylesheet" href="styles/main.css" type="text/css">
    <script type="text/javascript" src="touch2/sencha-touch-debug.js"></script>
    <script type="text/javascript" src="app.js"></script>
</head>
<body></body>
</html>

app.js

Ext.Loader.setConfig({
    enabled : true
});


Ext.application({
    name: 'MyApp',

    profiles: ['Tablet'],

    views: [
        // common Tablet & Phone views 
    ],

    models: [

    ],

    controllers: [
        'Main'
    ],
    launch:function(){
        Ext.Viewport.add(Ext.create('MyApp.view.Main'));        
        //Ext.Viewport.add(Ext.create('MyApp.view.tablet.Main'));
     }        
});

Good, now you have the two pivotal files in place and Ext.Loader will fetch framework components as needed for easier debugging.

First you set up your app's namespace (MyApp). That means that all your future classes will be defined under MyApp namespace.

Then you have defined the two main profiles. Tablet and Phone. They tell your app how to behave in different environments. Specify as many (or none) here.

Next, you've set up views, models, and controllers that are shared between the two profiles. They don't care whether you're using the app on a phone or a tablet.

Let's continue with our Tablet profile

app/profile/Tablet.js

Ext.define('MyApp.profile.Tablet', {
    extend: 'Ext.app.Profile',

    config: {
        views: [
            'Main'
        ]
    },

    isActive: function() {
        return !Ext.os.is('Phone');
    },

    launch: function() {
        Ext.create('MyApp.view.tablet.Main');
    }
});

Pretty self-explanatory. Config object hold your views/models/controllers that are specific to the profile. They won't be used (included) if you're running the app on a smartphone.

isActive method needs to return true or false after evaluating the environment. I specifically said that Tablets are all non-phones. Logically that's incorrect, but I decided to play this way for simplicity. The more correct way would be

return Ext.os.is('Tablet') || Ext.os.is('Desktop');

The final bit of a profile is the launch method. It tells the app what to do when the app is launched in particular profile. MyApp will create the main view in Ext.Viewport.

Note that Ext.Viewport is an instance of Ext.Container that has already been added to DOM on app start.

Let's create our first view. It can be whatever widget you want, and I chose NavigationView.

app/views/Main.js

Ext.define('MyApp.view.Main', {
    extend: 'Ext.navigation.View',

    config: {
        fullscreen  : true,

        items: [
            {
                title: 'My Great App'
            }
        ]

    }
});

It's fullscreen (100% width&height) and it immediately creates a TitleBar with title My Great App.

Have you noticed that we just defined MyApp.view.Main, but the app is going to expect MyApp.view.tablet.Main? Exactly because I wanted to show how you can reuse views between profiles. It's only useful if we're changing bits of them depending on the profile.

app/views/tablet/Main.js

Ext.define('MyApp.view.tablet.Main', {
    extend: 'MyApp.view.Main',

    initialize: function() {
        this.add({
           xtype    : 'button',
           action   : 'coolBtn', 
           text     : 'Running on a tablet'
        });
        this.callParent();
    }
});

This looks great already. Just for the sake of extending I added additional button to the NavigationView. I'm going to set up a controller that will work with the button

app/controller/Main.js

Ext.define('MyApp.controller.Main', {
    extend: 'Ext.app.Controller',

    config: {
        refs: { 
            coolButton: 'button[action=coolBtn]' 
        },

        control: {
            coolButton: {
                tap: 'onCoolButtonTap'
            }
        },

        routes: {
            'show/:id' : 'showItem'
        }
    },

    onCoolButtonTap: function(button) {
        console.log(button === this.getCoolButton());
    },

    showItem: function(id) {
        console.log('Showing item',id);
    }

});

This is the awesome part, right here. Refs give us a quick access to components based on component query rules (button[action=coolBtn] means find my a xtype = button cmp that has property action = coolBtn). Refs add getter methods, too, as seen in onCoolButtonTap example.

Then I control the button and tell the app to monitor the tap event and assign a handler to it.

Another smart addition to the MVC pattern are routes. They will detect "commands" in your URI path, e.g. http://localhost/#show/7482 and execute them through the provided showItem handler.

Summary

I think that now you have the basic idea of how to start with your MVC app. With some curiosity you can expand the knowledge and create awesome apps.

Note that I've written this out of my head and haven't tested. Let me know if you find a typo or something.