Some ways can allow you to develop Desktop applications also with the help of Web Technologies. It is SPAs who reduce the differences between the actual desktop applications and Web Enabled Desktop applications.
Now few questions arises:
- What is SPA or Single Page Application?
- Why to write SPAs?
- What is Routing?
- How to create SPA?
- How does it help in Hybrid mobile or Desktop app development?
For quick view, this is what we are going to build:
What is SPA or Single Page Application?
According to Single page apps in depth book,
Single Page Applications are distinguished by their ability to redraw any part of the UI without requiring a server roundtrip to retrieve HTML.
This is achieved by separating the data from the presentation of data by having a model layer that handles data and a view layer that reads from the models.
And its pretty much convincing. More can be read from this book’s site, but a basic understanding is pretty much clear from the above citation from the book.
And the can be expected to work on following principles:
- Write-only DOM
- Models are the single source of Truth
- Views observe model changes
- Decoupled modules that expose small external surfaces
- Minimising DOM dependent-code
Why to write SPAs?
The main reason behind writing the Single Page Application is to create a close-to-native-app like User Experience. It enables:
- Component wise development
- Modularisation and Maintainability of code
- Different Abstraction Layers for Data Access
- Minimise the DOM access
- Template Support
What is Routing?
In terms of the Front end development, Routing is a way to give state to the Web Apps with the help of URL hashtags (#/profile, #/profiles/@time2hack, etc.)
For modern browsers it works with the History API of HTML5. For older browsers, URL keeps changing like visiting new pages.
With routing in SPAs we can achieve:
- State in Web App
- URL based feedback of the page
- Easy navigation directly with URLs for users who are more experienced with the application
- Browser’s back and forward buttons are fully functional
How to create SPA?
Yo create SPAs, we will need a library that supports the basic ingredients that we talked about earlier in the post.
We can choose from many like AngularJS, Aurelia, Backbone, Knockout etc. But I will go ahead with the AngularJS as for a basic SPA design, it doesn’t has any dependency on third party lib.
So going ahead, we will design it Contact Store Application as a SPA. Right now it has modal pop ups to create new states bit everything resides there. And earlier we had used jQuery to create that application, and we will use the local storage to store and access our data in the application.
We will use routes like #/contacts, #/contacts/1xxx, #/contacts/add etc. to navigate on various states in application. For routing support we will use ngRoute, a routing module from AngularJS team.
The routes configuration goes in the config function of module. The sample routes and its config looks like this:
How does it help in Hybrid mobile or Desktop app development?
Now when we have SPAs, here also files and data are hosted on device but not all. As the main page loads, it loads all the other components from other HTML pages. And on navigating into the application, it is a smooth transition as the whole page is not getting refreshed but only the component. The pages hosted remotely are also smaller in size as they need to hold the component template.
So this way SPAs reduce the Hybrid Mobile app size reducing the file size and processing requirement on device. And the AJAX requests will cost less data over internet.
Contact Store Application
For this application, the major files will be one Main Index page where App will run, main app.js page where all the app initialization will happen and on controllers.js file which will have all controllers. We would be using Twitter Bootstrap for basic designing purpose. We will also need ngRoute for routing purpose. ngRoute can be downloaded from here. The direct links are https://code.angularjs.org/1.3.16/angular-route.js and https://code.angularjs.org/1.3.16/angular-route.min.js.
The directory structure will be as follows:
All the files will be linked into the index.html. Here is the basic code of index.html
Initialization and Configuration
We will create our app by `angular.module`. This will take two parameters, one is the app name and other is the dependency array. As we have dependency on `ngRoute`, it will be listed in the dependency array as string.
So the complete code to create the app will be `angular.module(‘contactApp’,[‘ngRoute’]);`.
Now this app needs to be loaded in the HTML. This can be done by `ng-app` directive, and it takes the name of the angular app that will be handling that part of HTML. This directive can be written on any small section of page, but for SPAs we need full control over page in the angular app. So we will have this directly in our HTML tag of page.
Now as we have bootstrapped the application, that’s all for basics. But as we have ngRoute in our dependency, it needs to be configured for various routes.
We have already seen the code for route config in this post, here is the complete config of routes for contacts application:
Templates and Controllers
As it can be seen from the config section that what are the main controllers and templates in our contacts application. Following is the controller.js having all the controllers.
It is also clear that what are the templates used in this application. Following are the codes for templates:
For data interaction we are using the Session storage of Browser storage. How to use localStorage and session storage? you can read about it in previous post here.
We picked the exact factory code from there to exploit it here. There are two functions `memorize( key, value )` and `recall( key )` in the factory named as `storage`. This factory is written in app.js file. And there are two main lines of code to use these function with our contact store application:
- `memorize` as `storage.memorize( ‘contacts’, JSON.stringify( $scope.contacts ) );`
- `recall` as `$scope.contacts = JSON.parse( storage.recall( ‘contacts’ ) );`