Before reading this article please goes through the following articles.
- Introduction to Sencha Touch 2
- Hello World App using Sencha Touch 2
- Sample form application using Sencha Touch 2
- Dealing with containers in Sencha Touch 2
- Working with DataBound Controls
- Introduction to MVC in Sencha Touch 2
Introduction:
In the last article we saw what MVC is and how it works with Sencha Touch. In this article we will create our first MVC application using Sencha Touch. As in the last article I already said that MVC here in Sencha Touch is in the client end of the MVC architecture.
In this article we will learn how to create a MVC application by creating a MVC structure and how the Sencha Touch framework fits into MVC. Sencha has built-in support for MVC and Sencha supports the entire application life cycle from generating applications to deploying it to production. In this article we will not use any tools or anything to generate or to build the application. In our forthcoming articles we will make this task easy. So here we will start our application development in a traditional way.
Step 1:
Launch your Visual Studio and create a blank website without any page. Just add a web.config file for some configuration setting. Add a system.webServer tag to the config file to respond the JSON MIME type as in the following:
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
Step 2:
Create a directory structure like the following image.
Here in this article our purpose is to create one main list and to open the detail page upon clicking of the list item. From this you will get a clear idea of how Sencha works with MVC. Here you will get the idea of loading a Store binding to the Model, how the Controller works between the flow, and so on.
One more benefit of Sencha is that it places the classes in the namespaces hierarchy. Hence we create the main app folder and inside it create four different folders to place our Controllers, Views, Models and Stores. Except add CSS and src folders that contain the CSS and framework script files taken from Sencha.com.
As in our first article we saw that Sencha Touch applications are single page applications so we need to add only one HTML page and one entry point js file named app.js.
Proposed Flow:
As we already know, Sencha Touch is a client end framework hence what it will do is the following. First the user makes a request to index.html and index.html is loaded into the user’s browser with all other files (Models, Views, Controllers, Stores, entry point file and framework file). From here our actual MVC starts.
Here first we are loading data from a JSON file located in the server with the name "users.json". What we will do is we will load the data from this JSON file into the Model using the Store so you will get the idea of how to load a Store and how to make a server request. As we saw in the last article the Store is responsible for talking with the back-end server.
Step 3:
Next you need to add our js classes so add one Controller, one Model, one Store and three different Views. So now you have the question, why should we add three Views, so here is the reason. Because one View will be our Main View and will never be removed from the viewport, we will simply replace the inner content of this View with other Views. This View will be a type of Master View to provide a consistent look to the application. Other two Views will be used, one for displaying the list and one for displaying the details page. Hence add three Views with the name Main, UsingListView and UserDetailView.
Step 4:
Create an entry point file named app.js and write the following code.
Ext.application({
name: 'SenchaApp',
requires: [
'Ext.MessageBox'
],
controllers:['UserController'],
views: [
'Main',
'UserListView', 'UserDetailView'
],
models: [
'UserModel'
],
stores: [
'UserStore'
],
launch: function() {
// Initialize the main view
Ext.Viewport.add(Ext.create('SenchaApp.view.Main', { fullscreen: true }));
}
});
In the snippet above you can see it starts with Ext.application that extends to the main application class of the Sencha Touch framework. Next you can see the name where we can specify any name or the name of the application. This name is useful for organizing your other classes in the namespace hierarchy. This app.js is the core file and contains information about all Views, Models, Stores and Controllers. When we specify this attribute here then we need not to refer our other classes on the HTML page, this attribute automatically downloads all the classes in the client browser. If you have a other script file and need to download them then you can specify those files in the requires attribute that will do rest of the work for you.
Next here we have a launch function with the entry point for our application. Here we are creating an instance of our Main View and adding it to the view-port. Next we will create our Main View. Here you can see how we have instantiated the Main View using the proper namespace. This specifies that in our View folder we have a file name called Main.js. From now onward we will use this for our Store, View, Models and Controllers.
Create Main View
Our next step is to create a Main View. As I already explained, this Main View is like a Master View that will provide a consistent look to our application. Add the following code to your Main.js file.
Ext.define('SenchaApp.view.Main', {
extend: 'Ext.NavigationView',
xtype: 'main',
fullscreen: true,
config: {
id:'mainView',
items: [
{
xtype: 'userList',
title:'User List',
height:'100%',
}
]
}
});
In the snippet above you can see we have created our Main View. In Sencha Touch whenever you need to create your custom class then user Ext.define with the namespace but make sure when you are defining a class with certain namespace then the file must be available at the location. Here I’m defining the "SenchaApp.view.Main" class and I have this file located in the view folder. Next here you can see we are extending this class from Ext.NavigationView that is the class defined in the Sencha framework from the above statement that is clear that Sencha has a strong inheritance feature of Object Oriented Programming. You can create your own class and can extend other classes from that. Once you have created the class that extends to the navigation view then this will add a default title bar that is sharable with other Views that we will add in this Main View. Here we added a userList type of control as an item in the Main View.
When you create a class and specify xtype for the class then this is your own custom xtype and you can use it whenever you need by simply specifying xtype:’to xtype specified in your classes.
Create User List xtype
In the previous step we created a Main View and added a userList to it as an item so we will create the xtype that is our custom control so add the following code to the UserListView.js file.
Ext.define('SenchaApp.view.UserListView', {
extend: 'Ext.List',
xtype: 'userList',
config: {
itemId: 'userList',
store: 'UserStore',
itemTpl: '{Name}'
}
});
Here we are creating a list control that extends to the Ext.List control of Sencha framework. You can see in the above snippet that again we are following namespace conventions since well we have a given xtype attribute that we can directly instantiate as we did in our Main View. Since we already know that a List is a data-bound control and requires a data-source hence we have specified the Store property so next we will create a Store.
Create Store
Here we will create a Store that will load the data from the user.json file from the server. So add the following code to the UserStore.js file:
Ext.define("SenchaApp.store.UserStore", {
extend: 'Ext.data.Store',
storeId: "usersStore",
config: {
model: "SenchaApp.model.UserModel",
autoLoad: true,
header: {
"Content-Type": "application/json"
},
proxy: {
type: 'ajax',
url: '/users.json',
reader: {
type: 'json',
rootProperty: 'users'
}
}
}
});
The code above you can understand, it is nothing but creating an ajax proxy specifying an URL and reading the data and filling in the data into the Model. Here we specified the Model also for the Store. We need to tell the Store where to fill the loaded data. So next we will create a simple Model class.
Create Model
Here we will create our data-model class that is extended from the Ext.data.Model framework class. The Model contains only the field’s information.
Ext.define("SenchaApp.model.UserModel", {
extend: "Ext.data.Model",
config: {
fields: [
{ name: "Name", type: "string" },
{ name: "City", type: "string" },
{ name: "Points", type: "int" }
]
}
});
Create Detail View
As per our flow we are opening the detail page when the user clicks on a list item therefore add a Detail View first.
Ext.define('SenchaApp.view.UserDetailView', {
extend: 'Ext.form.Panel',
xtype: 'userDetail',
config: {
itemId: 'userDetail',
title: 'User Details',
fullscreen: true,
items: [
{
xtype: 'textfield',
name: 'Name',
label: 'Name'
},
{
xtype: 'textfield',
name: 'City',
label: 'City'
},
{
xtype: 'textfield',
name: 'Points',
label: 'Points'
}
]
}
});
Here the Detail View is nothing but an extension of the from.Panel class of the framework and contains controls like TextBox to hold field information of the Model. While creating your Detail View keep in mind that whenever you want to load Model data into the form the form controls like textboxes and so on must have the same name property as the field in the Model.
Create Controller
Our last step is to create the Controller that is responsible for handling user actions, load Store, binding data to the View and returning the View.
Ext.define('SenchaApp.controller.UserController',
{
extend: 'Ext.app.Controller',
views: ['SenchaApp.view.UserListView', 'SenchaApp.view.UserDetailView'],
config: {
control: {
userList: {//add event for the component
itemtap: 'onUserTap'
}
},
refs: {//this section automatically generates getter and setter method for the component
userList: 'list[itemId=userList]',//getUserList() gives user list
mainView: '#mainView',//getMainView() gives main view
}
},
onUserTap: function(list, index, target, record, e, eOpts) {
var me = this;
var nav = me.getMainView();//getter method
//create model add data here we get the record from list's tap event. you can load store seperatly
also
var model = Ext.create('SenchaApp.model.UserModel', {
Name: record.data.Name,
City: record.data.City,
Points:record.data.Points
});
//create new detail view
var userdetailsView = Ext.create('SenchaApp.view.UserDetailView');
//set created model with data to newly create view
userdetailsView.setRecord(model);
//push this new view to main view
nav.push(userdetailsView);
}
});
In the above snippet we defined our own Controller class by extending the app.controller of the framework. The Controller contains the information about the Views and Stores. Next in the config section of the Controller class you can see we have given control and refs attributes that are useful to identify the control in the View or the View itself. As you can see we have given a ref to "list[itemId=userList]" that is nothing but our list view that we defined earlier. As you know the list has a data-bound control and has multiple events so in the control section we used the same selector name to specify what action needs to fire when the list item has been tapped. Here when we define the selector it automatically creates getter and setter methods for you. For example here we have used a userList as the selector so we can use the "this.getUserList()" method that will return the list control.
Next you can see we have specified an itemTap event for the list and we specified the function as onUserTap. Now whenever the list item is tapped by the user this function will be fired. This function contains code to create a Model with a record, creates a new Detail View to set this Model to the Detail View and adds a Detail View to the Main View. Here we did not use a Store because we already have data bound to it and in Sencha on any data event in databound controls gives the specific record as the parameter.
Conclusion
In this way we have completed our simple MVC application suing Sencha Touch 2. In the next article we will see how to perform CRUD operations using MVC so stay tuned.