Earlier this week we introduced newer Mobile Packs, Mobile SDK 2.0, Mobile Templates and Mobile App Gallery — all designed to make it easier and faster for you to create mobile apps on the Salesforce Platform. One of the newer mobile packs is based on Knockout (aka KnockoutJS). In this blog I’m going to walk you through how it works. If you’d like to get it up and running and try it out, follow the step-by-step instructions in this “Getting Started.”
What is Knockout and Why Knockout?
To understand it better, let’s take a look at the below picture from their tutorial (click on it to see it in full screen).
How Knockout Works (High Level):
2. Then create a JS class and make model’s properties (like firstName, lastName etc), instance properties of this JS class (like this.firstName, this.lastName, this.someButtonFunction etc). In KO, this class called a ViewModel class. For Example:
3. Finally, ask KO bind an object of ViewModel class with the actual View by calling:
After step #3, Knockout will take care of updating views when model data changes and updating the models when there is change in the views without us having to do all those things. That’s the gist but for more please go through their excellent tutorials here.
Mobile Pack for Knockout
Mobile pack for Knockout is essentially a set of example ‘Contacts’ apps that shows how to use our Mobile SDK and KnockoutJS framework and easily talk to Salesforce backend. They are ‘single-page’ apps but with multiple views (list view, details view and edit view). They use Twitter Bootstrap as a UI framework and come in various versions depending on deployment and code locations (Heroku, Visualforce and Cordova-Hybrid).
To understand where KnockoutJS, Twitter Bootstrap etc fits in, let’s take a look at the overall architecture.
As you can see from the above pictures, you can create 2 kinds of apps (with at least 6 different variations) using the Mobile Pack:
1. A mobile web app that runs in the browser.
1.1 Hosted on Heroku (using Node.js server)
1.2 Hosted on Visualforce.
2. A hybrid app using Mobile Packs (this is excluding pure-native Mobile SDKs).
2.1 iOS cordova hybrid app with files locally stored (on-the-device)
2.2 iOS cordova hybrid app with files served from Visualforce
2.1 Android cordova hybrid app with files locally stored (on-the-device)
2.2 Android cordova hybrid app with files served from Visualforce.
Irrespective of what kind of Mobile Pack app, they all more or less use the following set of files:
- boostrap*.css – Twitter Bootstrap as a UI framework (for look and feel)
- sammy-latest-min.js – Sammy.js (as routing library to make it single-page app; Knockout doesn’t natively support it)
- jquery.min.js – JQuery for dom manipulation via Knockout
Salesforce OSS libraries:
- knockout-force.js – A bridge between your app and smartsync.js to perform CRUD operations
- smartsync.js – A library thats a wrapper to mobilesdk.forcetk.js and helps sync data between app and Salesforce.
- mobilesdk.forcetk.js – A popular Salesforce REST api library that actually does the AJAX calls to Salesforce.
- cordova.force.js (Hybrid only) – A Cordova extension to help with OAuth and Salesforce smart-store.
- forcetk.ui.js (mobile web only) — An authentication library that helps with OAuth, login and logout of mobile-web apps.
App’s own JS files:
- init.js – Bootstraps and initializes the app
- app.js – Main app where all the main app business logics and ViewModels reside.
Creating a ‘single-page’ Contacts App
Before we go ahead let’s remember that our example Contacts app (Mobile Web – Heroku Bootrtrap Node.js) is designed as a ‘single-page’ app. This means once the app’s index page is loaded, it’s never reloaded but instead different ‘views’ (list view, details view etc) are simply added and removed to existing DOM by simply changing hash or anchor part of the url.
To achieve this we use Sammy.js’s routing and some tricks that can be described in 3 parts:
1. First, we create a div container to hold views like below:
<!– This is the main container where different views will be inserted (by SammyJS) –>
<div id=”mainContainer” class=”container”></div>
2. Then, we create ‘routes’ in SammyJS for each views like below:
3. And finally, reapply Knockout binding after a new-view is injected (so that Knockout now works for this new view).
Defining a Salesforce Object
One of the first things you want to do when playing around with mobile packs is to describe a Salesforce object so that you can perform CRUD operations on it. Thankfully knockout-force.js library provides KnockoutForceObjectFactory to make this trivial. And further help perform CRUD and search operations on top of that object. For example, in our contacts app we can create a Contact-class by setting fields, type, orderBy etc. like below:
And you can then perform CRUD operations like:
Contacts App Work Flow – Bringing it All Together
Now that you are familiar with the architecture and various parts of the app, let’s take a quick look at the work-flow to understand how it all comes together.
Step 2: Index.html page is rendered (in Cordova version, then native Salesforce OAuth is displayed).
Step 3: Once the user signs in using OAuth, after the callback, it ultimately calls ‘initApp’ function in init.js. This simply initializes everything with real Salesforce user’s authentication information and redirects to ‘/contacts’ route.
Step 4: Once /contacts route is triggered, the below code sets the list view and also sets the ViewModel via koApp.setViewModelByRoute(‘/contacts’)
Step 5: The change in route also triggers ‘changed’ event in Sammy.js and calls ko.applyBindings on currentViewModel
Step 6: By this step, the view is already changed to ‘list’ view and all the bindings are applied. But if you take a look at the ContactListViewModel, you will see that the minute it became ‘current’ viewModel (due to step 4), it makes an AJAX call to Salesforce to get list of contacts. And once those Contacts are returned by the server, Knockout will do its magic of automatically updating the views.
Step 7: After this point steps 2 through 6 is repeated with different ViewModels and routes for other views and user actions.
If you have read till this point hopefully you have gotten an understanding of how to build Knockout based single-page mobile apps. Now if you haven’t already, I highly encourage you to go through Knockout’s tutorials and take a look at source code for other variations (3 of them) in Knockout Mobile Pack samples github repo.
– Raja Rao DV (@rajaraodv)