About this book

Sencha provides one of the most popular frameworks to build RIA applications (using ExtJS) and HTML5 compliant mobile applications (using Sencha Touch). Creating an application is always easy, but creating a highly maintainable and scalable application is challenging without having solid architectural practices in place.

"Sencha MVC Architecture" covers all the aspects, from project design to building and packaging, creating and delivering an enterprise-class application by applying Sencha MVC Architecture. Every concept is supported with a functional code, which you can quickly try out and also understand how it works.

The book presents the general MVC architecture and presents a case for the client-side MVC architecture and their importance. You will learn why we need to have client-side MVC architecture and how the concepts map to the Sencha MVC Architecture. You will then learn how to create an application in ExtJS as well as Sencha Touch by applying all the concepts and classes of Sencha MVC Architecture. The step-by-step approach helps you build a working application without getting into the detail of the constructs yet explains how things work. The later part of the book will explain the Sencha MVC Architecture constructs in detail – class system, loader, controller, etc. and the best practices introduced by the framework. The end of the book will walk you through the challenges that you will face when you model your application using the Sencha MVC Architecture and also show you how to overcome each one of them. You will learn how to make use of the tools to manage your project beginning from the project creation to delivery.

Publication date:
November 2012
Publisher
Packt
Pages
126
ISBN
9781849518888

 

Chapter 1. Sencha MVC Architecture

MVC architecture is a well-known and a famous architecture. In an application, if there is a view (for example, a form to create payment into a system) and a user would use it to interact with the system, MVC architecture comes as the default and preferred architecture. It is the favorite architecture to model our application so that the presentation logic can be separated from the business logic. In this chapter, we will look at the MVC architecture in general, and understand how it is mapped to Sencha MVC Architecture.

In this, and the subsequent chapters, we will be demonstrating the concepts using some functional code for which the following softwares are required:

  • Eclipse 3.3 or above with JEE (for example, Helios) and JavaScript (JSDT) support

  • Oracle Java JDK 1.5 or above

  • Ext JS 4.1 library

  • Sencha Touch 2.0 library

  • Android SDK

  • ADT plugin

  • Apache Tomcat 6.0 or above

Before we get any further, we would need a development environment to be set up, so that we are able to build, deploy, and test the application. For brevity, we will not be covering how to set up the development environment in detail. The following are the high-level steps to get the project set up:

  1. Create a Dynamic Web Project workspace in Eclipse.

  2. Create a ch01 folder under WebContent where we will be keeping the code related to this chapter.

    Tip

    Downloading the example code

    You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com . If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

    After creation, your project should look as shown in the following screenshot:

  3. In Eclipse, go to Window | Preferences.

  4. Expand Server, go to Server Runtime Environments, and add an entry for Apache Tomcat shown as follows:

  5. Go to the Servers perspective and add SenchaArchitectureBook to the Configured list, shown as follows:

  6. Now you will be able to publish and start the server to see that the project is deployed successfully. You should be able to access the http://<host>:<port>/SenchaArchitectureBook/ URL to access the application.

Throughout this book, for the parts referring to Sencha Touch, we will be using the WebKit browsers, for example, Chrome and Safari, on the desktop to demonstrate the concepts. However, if you intend to test them on the real device, the steps would be more involved ones and you can refer to Chapter 1, Gear up for the Journey from the book Sencha Touch Cookbook, Packt Publishing, for detailed steps to set up the environment for Android, iOS, and Blackberry devices. Also, the book assumes that you have done some level of Ext JS or Sencha Touch development and are aware of the components and the programming model of Sencha.

 

Why Client-side MVC architecture


The MVC architecture is all about organizing the code in the form of models, views, and controllers. Models maintain the state of the application, views take care of the presentation of the application state, and controllers provide the much needed functionality to handle the user action and carry out the business logic execution as part of it, which changes the application state. The complete interaction between the pieces—model, view, and controller—is depicted in the following diagram. The solid lines show the flow of logic in terms of method invocation, whereas the dotted lines show the flow of events:

The previous diagram depicts the holistic view of the MVC architecture and how the different pieces of the architecture interact with each other in order to address the specific goals that the architecture promises to address. In this book, we do not intend to redefine and explain the complete MVC architecture. However, you may read more about the architecture at http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller.

Traditionally, in a web application, MVC architecture has been implemented on the server side to keep the view logic away from the business logic. In a typical web application, the server side code is structured in the form of model-view-controller to benefit from the structure to make the application more maintainable, allow parallel development, align the application with the Progressive Enhancement goals, and so on. In this case, the view code takes care of sending the (X)HTML, CSS, and JavaScript to the browser as part of the response in order to show the desired view to the user (for example, a grid showing a list of users with a button to edit the user address). The browser renders the HTML to show the content using the mentioned HTML tags (for example, a <table> tag to show the users list), uses CSS to style the content (for example, show the alternate rows with a different color), and uses JavaScript to add interactivity to the view and take care of the behavior (for example, on clicking the Edit button, showing a form to edit the user address). This has been depicted in the following diagram where the complete MVC is implemented on the server side, whereas on the browser side, JavaScript, CSS, and HTML is used:

Implementation of the previous architecture cleans up the server-side code. However, the browser-side code remains very messy with the HTML, CSS, and JavaScript intermixed. This gets multiplied when a considerable amount of code is written to run inside the browser, to render the view, and handle the interactions with the user, for example, as in Rich Internet Applications (RIA) . In addition to that, given the flexibility JavaScript offers, it makes the matter worse where people do things such as use the variables without defining them, and write functions and use them without worrying about writing object-oriented JavaScript. The need for the code that runs inside the browser does not differ much from the one that runs on the server side, hence the development principles (maintainability, reusability, and so on), which apply to the server-side code, also apply to the browser-side code. HTML and CSS form the view, JavaScript becomes the controller, and the objects, containing the state of the UI, form the model.

Effectively, there is a need to have two MVC patterns in the application, one on the browser side and the other on the server side, to reap the complete benefit of the architecture. The following diagram depicts browser-side MVC architecture and how it would interface with the server-side MVC:

View is the code that produces and renders HTML tags and applies CSS to them (for example, producing the <table> tag to show the users list with the alternate rows highlighted with a different color). Model contains the state of the application (for example, the list of users with their address details) in the form of one or more JavaScript objects/variables. Controller is a part of JavaScript taking care of the behavior part of the UI (for example, the onclick handler of the Edit button). Cache usually maintains the collection of models and provides a convenient way for the browser-side application to fetch the state and state information.

 

Why Sencha MVC architecture


Now that we understand the need of having MVC architecture on the client side, let us see why the Sencha MVC architecture was introduced as part of the Sencha Ext JS and Touch frameworks.

Let us look at the following code, written using Ext JS, which shows the list of users (from a users.json file) and shows an Edit User window with a form, populated with the selected record detail, when an entry in the list is double-clicked:

Ext.onReady(function() {
  
  //Define the user model
  Ext.define('User', {
    extend : 'Ext.data.Model',
    fields : [ 'id', 'name', 'email'],
  });

  //Define the Users store, which uses the User as the model 
  //and loads models from the users.json file
  Ext.define('Users', {
    extend : 'Ext.data.Store',
    model : 'User',
    autoLoad : true,	//load the data into the store as soon as it is initialized

    //proxy configuration, which is used to load the data
    proxy : {
      type : 'ajax',
      api : {
        read : 'data/users.json'
      },
      reader : {
        type : 'json',
        root : 'users',
        successProperty : 'success'
      }
    }
  });

  //Create an instance of the store that we defined above
  var store = Ext.create('Users', {});

  //Create the viewport which shows a grid loaded with the
  //user information from the store
  Ext.create('Ext.container.Viewport', {
    items : [ {
      xtype : 'grid',
      title : 'All Users',
      store : store,
      columns : [ {
        header : 'Name',
        dataIndex : 'name',
        flex : 1
      }, {
        header : 'Email',
        dataIndex : 'email',
        flex : 1
      } ],
      //event handlers
      listeners : {
        itemdblclick : function(view, record) {
          
          //Create a window and show a form panel with the values
          //populated from the record
          var win = Ext.create('Ext.window.Window', {
            title : 'Edit User',
            layout: 'fit',
            autoShow: true,
            height: 120,
            width: 280,
            items: [{
               xtype: 'form',
               padding: '5 5 0 5',
               border: false,
               style: 'background-color: #fff;',
               items: [
                 {
                   xtype: 'textfield',
                   name : 'name',
                   fieldLabel: 'Name'
                 },
                 {
                   xtype: 'textfield',
                   name : 'email',
                   fieldLabel: 'Email'
                 }
               ]
             }],
             buttons: [{
                 text: 'Save',
                 action: 'save',
                 handler: function() {
                   alert('Save!');
                 }
               },
               {
                 text: 'Cancel',
                 action: 'cancel',
                 handler: function() {
                	 alert('Cancel!');
                 }
            }]
          });
          
          win.show();
          win.down('form').loadRecord(record);
        }
      }
    } ]
  });

});

The example uses a users.json file, which has the following content:

{
  success: true,
  users: [
    {id: 1, name: 'Sunil',  email: '[email protected]'},
    {id: 2, name: 'Sujit', email: '[email protected]'},
    {id: 3, name: 'Alok', email: '[email protected]'},
    {id: 4, name: 'Pradeep', email: '[email protected]'},
    {id: 5, name: 'Ajit', email: '[email protected]'}
  ]
}

Ext.onReady acts as the entry point to the application and is called as soon as the Ext JS framework is loaded and initialized. In the previous code, the complete application logic is written inside a single file, say, app.js. To run the code, we would create an index.html with the following content:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title id="page-title">Account Manager</title>

  <link rel="stylesheet" type="text/css" href="<extjs folder>/resources/css/ext-all.css">
  <script type="text/javascript" src="<extjs folder>/ext-all-debug.js"></script>
  
  <script type="text/javascript" src="app.js"></script>
</head>
<body>

</body>
</html>

Replace <extjs folder> with the folder on your system where Ext JS 4 distribution was extracted. In my case, I kept it inside the ch01 folder. The following screenshot shows what the project structure will look like after all the files are created:

Publish and Start the server and access the http://<host>:<port>/SenchaArchitectureBook/ch01/index.html URL from your browser. You will see the users' list and when you double-click on an entry, you will see the output as shown in the following screenshot:

Now, let us review the code and understand, though it is a functional code and meets the requirement, why it is considered to be a bad application. There can be multiple ways to model this application with a varied number of files making use of the various object-oriented principles. However, I have presented the worst (well, still not "the worst") way to code the application to help us understand the demerits and then see how each one of them can be addressed by sticking to a well-defined architecture. In the previous code, we first defined a User model with their fields, which is used by the store to represent the data in memory. Then we defined a Users store, linking the User model with it. In the store, we specified the proxy information, which the store would use to load the data from the mentioned URL, data/users.json. We then created a viewport to which we added a grid panel, xtype: 'grid'. This grid panel uses the instance of the Users store that we created using var store = Ext.create('Users', {});. The grid shows two columns, Name and Email. We also registered the handler for the itemdblclick event on the grid panel. The handler code creates a window with a form panel inside it and two buttons, Save and Cancel. We registered the dummy handlers for the Save and Cancel buttons, which show an alert message when the user clicks on them. We then show the window to the user and load the form inside it with the model that we had received from the framework as the second parameter to the itemdblclick handler.

If we look more closely, the following issues are evident in the previous way of coding the application:

  1. If the grid has to be replaced with a different view component, say, a DataView component, the complete app.js code needs to be changed. For that matter, if any change is made to the view, model logic, and controller logic, then the app.js file needs to be modified, which makes the parallel development unmanageable in bigger projects.

  2. Reusability of the view is not possible. Also, reusability of the model and controller logic is questionable.

  3. Any change adds considerable testing effort as the testability of the code is really low. For example, if we choose to replace the grid with a data view component, then the complete code needs to be tested as the view logic is not separate from the controller.

  4. A person working on this project will only understand the project structure, how the code flows, and where what is written, and it takes a lot of training and documentation to make a newcomer (to the project) understand the project and the code even though the person has the technical skill. A person working on this project will have the same challenge if he/she has to move to a different Ext JS/Touch project in the organization.

  5. As the code structure does not follow any architectural guideline and best practices, for every project, a custom build process has to be developed and implemented for the build and packaging.

Until Ext JS 3.x, there was no MVC architecture. However, it was realized that given the rich functionality the framework offers, it was easy for people to divert from the best practices in a typical application development and introduce the problems that we outlined previously. The need was felt to have functionality in the framework, which enforces MVC architecture when it comes to application modeling and development. The benefits include the following:

  • As long as the applications follow the architecture, they work the same way, and hence it becomes a lot easier for anyone who knows one application, to understand and follow all the applications following the same architecture.

  • Sharing the code (view, controller logic, model and so on) across the applications becomes easier as all the projects follow the same folder structure, naming convention, and design, and hence a view written for one application can be used in another application.

  • Making the changes becomes a lot more manageable and reduces the overall testing effort considerably.

  • The Sencha MVC architecture uses class loading internally, which saves us from including all the JS files in the index.html and managing their orders manually. This comes as a great benefit to a medium to large application as there may be tens or hundreds of files.

  • We can use Ext JS build tools to create standard and optimized versions of your applications for production use.

In the next chapter, we will look at modeling the same application (or a slightly enhanced one) using the Sencha MVC architecture.

 

Sencha MVC architecture


In the previous section, we discussed about the need to have an MVC architecture implemented on the browser side. Given that Sencha Ext JS and Touch are Rich Internet Application (RIA) frameworks having various components such as grid, chart, and combo-box, which use a collection of models and components such as form panel, which uses a model, these components have been designed in such a way that a collection of models can be shared across them. For example, user list can be shown in a grid or in a combo-box. Sencha Ext JS/Touch introduces a cache of models, called store, which is shared between the components. A model or a store interacts with the server-side controllers. The following diagram depicts the architecture used in Sencha Ext JS/Touch:

  • Model is a collection of fields and their data. Models know how to persist themselves through the data package.

  • View is any type of component. Grids, trees, and panels are all views.

  • Controllers are special places to put all of the code that makes our application work.

  • Store acts as a cache, which contains a collection of models.

For example, our application is supposed to display the list of users, a User model will represent the fields, such as firstName, lastName, and address. A Users store will contain a collection of User models. A grid panel represents the view to show a nicely styled users' list. Controller will handle the events such as a double-click on the grid row to show a form to edit a user's information, or click on the Edit button to edit the details of a user's address.

Now, on the basis of the framework, we will see how the MVC architecture is mapped.

Ext JS 4.1

Ext JS framework introduced MVC in Version 4.0 for the first time. It shares a lot of common code with the Touch framework. However, there are certain subtle differences which we will see in the subsequent chapters. Since its introduction, various cleanups and fine-tuning have been done to make it consistent and efficient. The framework provides various classes, as shown in the following diagram, to help us build a true MVC-based application:

Ext.app.Application acts as the entry point in the MVC-based application. Use of this replaces the usage of the Ext.onReady method that is used to implement the entry point. Besides providing the entry point, the application also requires us to provide the dependencies in the form of controllers, which form the application, the stores, and so on. Controller, which extends Ext.app.Controller class, lists out the views and models that it will interact with. Based on the specified dependencies, the application loads the controller, which in turn loads the views and models and works with them to provide the desired view and allow the user to interact with it. Views are mainly the framework-defined visual components such as grid panel, form panel, tree panel, and buttons, or the user-defined components. In general, Ext.Component and Ext.container.Container are the base classes any view component extends to. Ext.data.Model is the base model class to define a model using the framework.

This object is used across various components to provide the application state. In addition to the models, the framework also offers a caching for the models in the form of the Ext.data.Store class, which can be passed to different components, such as grid, tree, and combo box, to show the data.

In Chapter 2, Creating an Application, we will discuss in detail each of these pieces.

Sencha Touch

As mentioned in the previous section, Sencha Touch is the foundation for MVC architecture. It was first implemented as part of it and later introduced to the Ext JS framework, as well. Similar to Ext JS, Sencha Touch supports Ext.app.Application , Ext.app.Controller , Ext.Component , Ext.Container , and Ext.data.Model , and they provide a similar set of functionality. However, there is an additional functionality called profiles, which is unique to the Touch framework. It allows us to define different profiles for different target devices (iPhone, iPad, Android phone, and so on). The profile functionality is offered by the Ext.app.Profile class and it consists of a collection of one or more controllers, one or more views, and one or more models. The Application class detects the profile applicable to the target device on which it is running and based on that, loads and initializes the respective controllers, models, and views. Store is available in Touch as well, and contains a collection of models. The following diagram depicts the components of the application architecture in Sencha Touch.

 

Summary


In this chapter, we looked at the MVC architecture and outlined the needs of having an MVC architecture implemented on the client side, which runs inside a browser. We then went on to see how we could have modeled our application without using Sencha MVC architecture and looked at the demerits of that modeling. We then looked at the benefits that one can get by following Sencha MVC architecture. Subsequently, we looked at the classes in Ext JS as well as Sencha Touch, which map to the model, view, and controller. In the following chapters, we will delve deeper into the specifics of the Sencha MVC architecture where we will see how to create an application using the Sencha MVC Architecture.

About the Author

  • Ajit Kumar

    Ajit Kumar has over 16 years of experience in technology areas ranging from embedded systems to large enterprise applications. He worked with various multinational corporations such as Honeywell, Hughes, Virtusa, and Convergys, before starting his own company—Walking Tree—which specializes in Sencha frameworks.

    Ajit has authored books on open source frameworks, including Sencha Touch Cookbook, Sencha Touch Cookbook Second Edition, Sencha MVC Architecture, and ADempiere 3.6 Cookbook, all by Packt Publishing, which he considers his way of thanking the awesome open source community!

    Browse publications by this author
Book Title
Access this book, plus 7,500 other titles for FREE
Access now