ExtJS and a Simple MVC (Model-View-Controller) – Tutorial – Part 1

  • Facebook
  • Twitter
  • Delicious
  • Digg
  • StumbleUpon
  • Add to favorites
  • Email

MVC – Model View Controller

has become quite the standard when developing highend software applications, but what has it meant for web applications? Lately, even on the web, it has become quite the “done thing”, especially with the support of frameworks such as Symfony and YUI (PHP). That’s why I will be taking a look at the new ExtJS 4.1 – JavaScript framework with MVC support.

Here at Mutinyworks.com we are not currently developing any products with ExtJS. So, I have been able to get stuck in to other activities.

I have to say, for a framework that I started off disliking, I have become quite the fan! Whether you use the framework for your product or application is a choice you’ll have to make and I think that is very dependent on the scale and/or complexity of the application you’re looking to create.

My opinion: If you want a rapid development framework that will help you build some pretty cool, “out of the box” user interfaces, then ExtJS is definitely something you will want to consider – especially now with the new MVC features of version 4.x. However – be warned: not only do I find the documentation fairly poor when it comes to less frequently used features, but ExtJS is also quite the fatso and can have the tendency to slow things down a bit. Having said that, I noticed this when I was trying to Ajax about 20 requests and dynamically build an interface out of those request … soo … that might have had something to do with it :) But on a serious note: Yes, it’s not the fastest but perhaps a price worth paying.

Getting started…

Right, let’s get started with building our first MVC in ExtJS. I’ll assume you have downloaded ExtJS (with the correct licence). Here is a link just incase:

Download

Now, we want to set up our document structure as follows:

  • Website Folder
    • extjs-4.1.0
    • app
      • view
      • controller

To begin with, we need to create a simple index.html in our top folder, in this case Website Folder and include our ExtJS library and css.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
    <head>
    <title>My ExtJS MVC</title>
    <link rel="stylesheet" type="text/css" href="extjs-4.1.0/resources/css/ext-all.css" />
    <script src="extjs-4.1.0/ext-all.js" type="text/javascript"></script>
    <script src="init.js" type="text/javascript"></script>
    </head>

<body>


</body>

</html>

As you can tell, I have included another file called init.js in my index file… This is where I am going to pack all my ExtJS code.

Our init is the core of our application and will allow us add Controllers, Stores, Models & Views. So let’s start our application by creating an init.js file.

Init

Now that we have our freshly created init.js we need to tell ExtJS where to start. This is done by Ext.application({ … }) Inside this function you can setup all your main application configurations. You can also preload stores, models and views that you want your application to handle. As a starting point we should created a simple application like the example below:

1
2
3
4
5
6
7
8
9
10
11
12
13
//First of you will need to enable to loader - dynamic dependency loader

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

Ext.application({

name: 'App', //name this as you like
autoCreateViewport: true, //set as true - it will seach for the Viewport.js file automatically
launch:function(){
//similar to jQuerys $(document).ready, fired on when application is ready
}

});

Right now, nothing will happen, as we haven’t created your viewport yet. I want to run through a few bits and bobs first. The config autoCreateViewport is a little misleading. What it should be called, in my opinion, is autoLoadViewport. However, what ExtJS will attempt with this configuration is to preload a viewport at the following location:

1
{Appname}.view.Viewport;

Views

Moving to our view folder in /app/view let’s create a Viewport.js for the application to preload. If you want to name your application (app) folder different from this example, then you will have to change the config name in init.js.

If you want to have the application and directory named differently you will need to use the config appFolder. Without setting appFolder the above Ext.application({}) example in init.js will build the location / paths of your application from the config name, i.e. App.view.*, App.controller.* etc.

Back to views – as we have configured the application to auto load the viewport, we better start by giving it something to load in the first place. In our js file Viewport.js add the following.

1
2
3
4
5
6
7
8
9
10
11
12
13
Ext.define('App.view.Viewport', {
     extend: 'Ext.container.Viewport',
     layout: 'fit',
     items:[{
          xtype:'panel',
          title:'hello',
          html:'this is a panel inside a viewport!',
          items:[{
               xtype:'button',
               text:'click me'
          }]
     }]
});

Some Basics

Bearing the above Viewport example in mind, I want to run over a few features. As you mave have noticed, layout:fit sets itself and the child elements (in this case, the panel) to fit the screen/window. There are a few layout configurations defined in ExtJS

xtypes

A nice little feature you have in ExtJS are xtypes. In the example above we have defined an item in the viewport as panel. This is a short hand of predefined Ext.panel.Panel.

Everything that is placed within the items config is displayed within that viewport, you can add Panels, Buttons, Grids etc… i.e. {item1},{item2},{item3}. Items can also house subitems and can change layouts but we’ll leave that for another day.

To create your own xtype, we need to use the config alias. This is handy as it provides us with a shorthand namespace to our own view configurations and helps when searching for particular components within a view while using functions like up() or down(). Let’s take a quick detour and create our own xtype now. For all the predefined xtypes go to the documentation

Staying in the folder view, create another .js file and name it MyPanel. Here we will create a simple panel with 2 buttons.

1
2
3
4
5
6
7
8
9
10
11
Ext.define('App.view.MyPanel', {
     extend:'Ext.panel.Panel',
     alias: 'widget.mypanel',
     items:[{
          xtype:'button',
          text:'button1'
     },{
          xtype:'button',
          text:'button2'
     }]
});

Remember! if you use alias to create your own xtype you must put ‘widget.‘ infront of the name (whatever you wish to call it) – in this case ‘widget.mypanel’.

Looking at your view folder, you should now see the following files:

  • Viewport.js
  • MyPanel.js

Currently, though, our new panel is still not visible to the viewport and in order to do so we will need to include it. For that to happen we need to take advantage of the config requires and redefine our viewport.

1
requires:['App.view.MyPanel'] //can add as many as you like using , comma

Your viewport should now look something like this:

1
2
3
4
5
6
7
8
9
10
// 'App' is the name of the application we gave in init.js under config 'name'

Ext.define('App.view.Viewport', {
     extend: 'Ext.container.Viewport',
     layout: 'fit',
     requires:['App.view.MyPanel'], //Name must be identical to that of the Panel define i.e. Ext.define('App.view.MyPanel', { ....
     items:[{
          xtype:'mypanel',
     }]
});

Note: when you require an item you can now call the item by its xtype (alias) without the term ‘widget.’

That was easy, huh?

Taking control

So we’ve created an application, a viewport and a panel… What if we wanted to catch the button clicks from in MyPanel? Maybe it’s time to add a little functionality and take control of those buttons. After all you can click to your heart’s content and nothing will happen.

Leave the view folder and head into controller. Here we are going to create a controller called MyController.js

1
2
3
4
5
6
7
8
9
10
11
12
Ext.define('App.controller.MyController', {
     extend:'Ext.app.Controller',
     init:function(){
          this.control({
               //Component listeners
          });

          this.application.on({
               //Event handlers
          });
     }
});

This is the best bit… using Controllers in ExtJS is an extremely powerful tool and if you put your mind to it you should be capable of controlling almost everything that ExtJS has to offer.

3 Important things to remember here…..

1. Every controller needs an init, This is a must… as the sencha documentation says

A template method that is called when your application boots. It is called before the Application‘s launch function is executed and so gives a hook point to run any code before your Viewport is created.

2. The fun parts… control allow you to listen for component events such as a button click. You can grab these events by using a selector and catching the desired event. An example is best I think. (place the following inside this.control({ … }):

1
2
3
4
5
6
7
8
9
10
11
'button': {

     //type of event to be caught

          click:function(){

               alert('a button has been clicked');

          }

}

3. this.application.on is extremely handy if you want to fire application wide events and I will show you how this is done in more detail in Step 2 (when it’s written :) )

Save the file… However, before you jet off and refresh your browser, open your init.js file in the root directory of your web application.

Let ExtJS do the work

Without any painful links to the controller, we will add the controller to the application similar to how we added MyPanel to the viewport, with a config like requires. ExtJS provides the following such configs:

  • controllers
  • views
  • models
  • stores

Anything that you need to access in your controller (yes, you can place it in there as well) or application, you place in one of the configs stated above. So for our purpose, place the following inside your init file underneath autoCreateViewport:true

1
2
3
4
5
6
7
8
9
...

autoCreateViewport: true,

controllers:['MyController'],

launch:function(){

...

Reload your application in your browser and you are all set to go!

Part 2

Firing application wide events and interaction with multiple controllers

16 thoughts on “ExtJS and a Simple MVC (Model-View-Controller) – Tutorial – Part 1

  1. Pingback: ExtJS and a Simple MVC (Model-View-Controller) – Tutorial – Part 2 | Mutinyworks.com

  2. Great tutorial,Please send me the second step tutorial link if their is any,i am beginner so i m looking for such tutorials,Thanks in advance…. :)

  3. Hello,

    Shouldn’t the MyPanel.js Items-list end without semi-colon? Now the items and also the MyPanel-define have semi-colons on the closing tags:

    Ext.define(‘App.view.MyPanel’, {
    ………
    items:[{
    .........
    }];
    });

  4. OMG I could not find a tutorial for version 4 and was going to have a bad day. Then I randomly found this. You are awesome. Know that you helped a very new developer learn something new haha!

  5. Thank so much for tutors, as I am new in Sencha Touch and Extjs4. but my question in extjs4. Please I have a question but not related to you post.

    Am building an app using tree-panel and dataview in extjs4, but i don’t just know how to get both of them working together.

    what i want to achieve is to have for example list of departmental names(All Dept, Human resources, I.T, Sales, Accounts, etc) under tree-panel, then details of staff(staff picture, staff name) displaying on the dataview.

    So at a click on Sales in tree-panel for example, it will display list and details of all staff(staff pictures and names) in the dataview.

    please, take a look at a related example(http://docs.sencha.com/extjs/4.2.1/extjs-build/examples/view/animated-dataview.html) of what i want to achieve, only that i want the tree-panel to take the place of the slider. kindly help me with a tutor.

    thank you.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>