A full HTML5 mobile development stack, including PhoneGap, trigger.io, Backbone.js, Require.js, jQuery Mobile, Sencha Touch, jqMobi, and Mustache. The lecture provides best practices towards developing a mobile application using HTML5 and Javascript.
2. Agenda
HTML5 or native?
HTML5 Mobile Development Frameworks
PhoneGap
Trigger.IO
UI Frameworks
jQuery Mobile
Sencha Touch
jqMobi
MVC with Backbone.js
Client Side Templating with Mustache
Modular Javascript with RequireJS
3. Go web or native?
Web Native
Cross-platform code. Smoother user interface.
CSS3 is very powerful, easy and More control and flexibility (for
flexible compared to Android and example, PhoneGap does not
iPhone UI libraries. export all native abilities).
Easy to patch / update because only You will need to write Javascript to
web assets need to be replaced. native interfaces if your back-end /
business logic is already
programmed using native code
All you need to know is Javascript
for all platforms.
Static elements and transitions are
still laggy.
4. My suggestion
Use WebViews when you need to have a complicated,
good looking user interface, and if you need it fast
User native UI when you need very CPU intensive, sleek
interface, and you are willing to invest a lot of work on it
Use a combination of both to gain both advantages! Use
native static elements (header, footer, page frames and
page transitions), and program the actual user interface in
WebViews
6. PhoneGap
Cross platform open source framework for writing mobile
apps
Write your program once, and compile an app for Android,
iPhone, BlackBerry, Windows Phone, and more…
Exports Javascript APIs for native phone control (camera,
GPS, filesystem, etc.) and has plugins
7. PhoneGap APIs
Accelerometer Events
Camera File
Capture Geolocation
Compass Media
Connection Notification
Contacts Storage
Device
8. Trigger.IO
Similar to PhoneGap, but commercial
Has a utility called forge which does the app building for
you, instead of opening 3 completely different IDEs to do it
yourself
Claims to outperform PhoneGap native bridge by x5
You should choose it if you can write your program in
Javascript only (no plugins)
Good for web, too!
11. UI Frameworks
If you decide to build all of your mobile UI using a web
framework, you should use a UI framework which saves time
with mobile-looking components
jQuery Mobile – Free, heavily backed by the community
http://jquerymobile.com/
Sencha Touch – Commercial, robust
http://www.sencha.com/products/touch
jqMobi – Haven‟t tried it, but it looks promising in terms of
performance, which is the Achilles heel of mobile web UI
http://www.jqmobi.com/
http://www.youtube.com/watch?v=MwNdWZsRXgk
12. The Fixed Toolbar Nightmare
Either you have a new device which supports real fixed
toolbars, or you simulate the scroll
jQuery goes with real toolbars & fallback support.
Fallbacks to statically positioned toolbars
Sencha Touch goes for compatibility and simulates the
scroll by moving the body up instead of letting the page
scroll down
If you really want both performance and compatibility - the
best solution would probably be… to use native toolbars
13. jQuery Mobile
jQuery Mobile does not use jQuery – you can use
whatever you want for DOM manipulation
Evolved a lot in the past year and is ready for real world
development
Although performance has improved a lot, it‟s still not
amazing. You might want to do a little more research
14. jQuery Mobile Features
Pages and sliding page transitions, toolbars (header,
footer, fixed), navigation pane, forms, themes and more
17. Comparison
Backbone.js, Spine.js – very similar libraries
Ember.js – has automatic updating templates, which are
voodooish, and bindings work a bit different
Ember should be nicer to program with, but Backbone
gives more control and performance
19. Backbone.js
Backbone.js is a minimal, popular, generic MVC
framework for writing heavy HTML5 web & mobile
applications
Who uses Backbone.js?
LinedIn, Soundcloud, Basecamp, Codiqa, and more
20. Backbone.js
Backbone.js makes you program user interface the right
way
An object model with inheritance
REST Sync
Can be used with jQuery/Zepto, MooTools, etc. for DOM
manipulation
21. Code with Backbone
Code without Backbone Code with Backbone
function createListView(id) { Var ListView = Backbone.View.extend({
tagName: “div”,
var listView = $(“<div>”).addClass(“list”) className: “list”,
.click(function(e) { events: {
if ($(e).is(“li”)) “click li” : “clickItem”,
$(e.target).addClass(“selected”); “keypress” : “deleteOnKeypress”
$(this).data(“selected”, $(e.target) },
.text()); clickItem: function(e) {
}).keypress(function(e) { $(e.target).addClass(“selected”);
if (e.keyCode == 8) { this.selected = $(e.target).text();
$(this).find(“.selected”).remove(); },
}); deleteOnKeypress: function(e) {
if (e.keyCode == 8) {
return listView; $(this.el).find(“.selected”).remove();
} }
}
var listView = createListView(); }
var listView = new ListView();
22. Quick REST Tutorial
REST = REpresentational State Transfer
It is a protocol which servers implement to give control of
the state of a data set (a collection of data items)
REST maps CRUD operations to HTTP operations
Collection Operations
HTTP GET = Read
HTTP POST = Create
Model Operations
HTTP PUT = Update
HTTP DELETE = Delete
23. Backbone MVC
Architecture
Server Model Database
Backbone REST Sync
Model View
Backbone.Model HTML + CSS
Model updated DOM Manipulation
according to With jQuery and
user interaction templating
Controller
Backbone.View DOM View Events
Model Events
24. Backbone Model
The Backbone.js Model represents a single data entity
It is usually bound to a view in such a way that every time
it changes, the view is updated accordingly (MVC)
change/delete
Model View
25. Backbone.js Model
Backbone fires “change” and “destroy” events when
specific models are updated or deleted.
Without regarding views, Backbone also automatically
synchronizes models back to the server on every change
Model
Server
26. Backbone Model
task.save({
title: “Get Rich”,
done: false
});
change:title
Model View
HTTP PUT /tasks/1
Server
27. Backbone Model
task.destroy()
destroy
Model View
HTTP DELETE /tasks/1 remove
Server
28. Backbone Collection
A Backbone Collection object stores a set of models of the
same type
It configures the REST endpoint in the server for the data
set
Model
Model Collection Server
Model
29. Backbone Collection
Backbone collections can fetch a collection from the
server
A “reset” event is fired when results from the server return
tasks.fetch();
tasks.bind(“reset”, this.addTaskViews);
HTTP GET /tasks
Collection Server
Model
Model
Model
30. Backbone Collection
Backbone collections have the “create” method, which
creates a new model
tasks.create({
title: “Hello, world!”,
done: false
});
tasks.bind(“add”, this.addTaskView)
New Model
New Model
Model
HTTP POST /tasks
Model Collection Server
New task ID: 3
Model
31. Summary - Backbone REST
Architecture
Model Operations
Collection Operations Collection
GET /tasks PUT /tasks/38
POST /tasks View Model DELETE /tasks/38
PUT /tasks/39
View Model DELETE /tasks/39
PUT /tasks/40
View Model DELETE /tasks/40
PUT /tasks/41
View Model DELETE /tasks/41
32. Backbone View
Views represent a model or a collection of models, and
are responsible for managing their child views
Backbone creates a DOM element with a specific class for
every new view, using the tagName and className tags
Or, Backbone can use a view which already exists in the
DOM, if el is defined
Backbone.View.extend({ Backbone.View.extend({
tagName : “div”, el: $(“#main-view”);
className: “section” })
}) …
<div id=“main-view”></div>
33. Backbone View
The View is the most important class of Backbone, since
it‟s actually an MVC controller. (Bad choice of words.
Check out spine.js for a better choice)
It translates the user actions into model changes
It updates the view when a model is changed
34. Backbone View
Let‟s create a todo item view, which represents a single
todo item in a todo list
var todoItemView = Backbone.View.extend({
tagName: “div”,
className: “todo”
});
View
35. Backbone View
Now let‟s add the model it is bound to
var todoItemView = Backbone.View.extend({
tagName: “div”,
className: “todo”,
model: todoModel
}); Model
View
36. Backbone View
Get notified when the model is changed by binding on
model change events, so we‟ll know we need to update it
var todoItemView = Backbone.View.extend({
tagName: “div”,
className: “todo”,
model: todoModel,
initialize: function() { Model
_.bindAll(this, “update”);
this.model.bind(“change”, this.update);
}
});
View
37. Backbone View
When checking off the task, we want to know about it. So
let‟s add a checkbox change handler
var todoItemView = Backbone.View.extend({
tagName: “div”,
className: “todo”,
model: todoModel,
initialize: function() { Model
_.bindAll(this, “update”, “check”);
this.model.bind(“change”, this.update);
}, events: {
“change .done-checkbox” : this.check
}
});
View
X
38. Backbone View
Now, let‟s toggle the task‟s “done” status in the function
“check”
var todoItemView = Backbone.View.extend({
tagName: “div”,
className: “todo”,
model: todoModel,
initialize: function() { Model
_.bindAll(this, “update”, “check”);
this.model.bind(“change”, this.update);
}, events: {
“change .done-checkbox” : this.check
}, check: function() {
this.model.save({
done: !this.model.get(“done”);
});
} View
});
X
39. Backbone View
Let‟s update the view when we receive the “update” event
var todoItemView = Backbone.View.extend({
tagName: “div”,
className: “todo”,
model: todoModel,
initialize: function() {
_.bindAll(this, “update”, “check”);
this.model.bind(“change”, this.update); Model
}, events: {
“change .done-checkbox” : this.check
}, check: function() {
this.model.save({
done: !this.model.get(“done”);
}); X
}, update: function() {
this.title.text(this.model.get(“title”));
if (this.checkbox.val()) { View
$(this.el).addClass(“checked”);
} else {
$(this.el).removeClass(“checked”);
}}
});
40. Rendering a View
When creating a new view, you must implement and call
its render function to build its inner elements
You can implement the render function in 3 ways
1. Don‟t implement it – if you are using an existing element
2. Use jQuery or another DOM library to build the inner
elements using code – results in ugly and unreadable code
3. Use a template to render the view – preferred method
41. {{ Mustache }} Templating
Mustache is a common logic-less templating library
Supports a wide range of languages
Simple syntax, yet powerful
Supports loops
You can use underscore.js templates, but they are not as
strong
42. Rendering using Mustache
Let‟s use jQuery‟s .html() function to fill our element with
the rendered template
Use Mustache.render with the view template text , along
with the models‟ data (we use toJSON to serialize the
model data so the template engine can use it).
Templat
Model
Backbone.View.extend({ e
render: function() {
$(this.el).html(
Mustache.render(todoItemTemplate, Mustache
this.model.toJSON()));
}
);
View
43. Updating a View
When updating a view, you may use two methods:
1. If you are using a template, you may use the render
function with the updated attributes again
2. Acquire handles to the DOM elements you created in the
render function and update each of them according to the
change.
The first method is a lot easier to implement, but when
you need performance, you should later on move to option
#2.
44. Optimistic Mode
Optimistic mode (Default)
Creates/updates views before confirmation from server
Gives better user experience
Wait mode
Creates/updates views after confirmation from server
Safer method
If you have business logic related to how your entities are
created which implicates on the views, you cannot use
optimistic mode
46. RequireJS
Modular Javascript library
Important when writing big projects
Loads modules asynchronously – allows the page to load
efficiently
Allows minification of the whole project into one file
47. How to use RequireJS
Boilerplate code example
https://github.com/ronreiter/webapp-boilerplate
RequireJS loads “AMD” modules (Asynchronous Module
Definition” as opposed to the company )
Normal modules add a global variable (jQuery adds $ for
example), or add method over a global variable (like jQuery
plugins).
This means that you CANNOT use normal libraries, without
wrapping them first.
I„ve wrapped them for you, so just download my boilerplate and
use it.
48. Code with RequireJS
Code without Require.JS Code with Require.JS
<script src=“foo1.js”></script> <script src=“require.js”></script>
<script src=“foo2.js”></script> <script>
<script src=“foo3.js”></script> require([“foo1”, “foo2”, “foo3”, “foo4”],
<script src=“foo4.js”></script> function(foo1, foo2, foo3, foo4) {
<script> foo1.do();
foo1.do(); foo2.do();
foo2.do(); foo3.do();
foo3.do(); foo4.do();
foo4.do(); });
</script> </script>
foo4.js: foo4.js:
// hmmm. Can I use foo1, foo2, and foo3? define([“foo1”, “foo2”, “foo3”],
// let‟s put foo4 as a global variable. function(foo1, foo2, foo3) {
window.foo4 = … var foo4 = …
return foo4;
});
49. RequireJS + Templating
Another awesome advantage of RequireJS is that it knows
how to load text files along with the modules, so you can
simply write your client side template files separately, and
load them when you need them
define([“backbone”, “underscore”, “jquery”, “text!listview.html”],
function(Backbone, _, $, listViewTemplate) {
… Mustache.render(listViewTemplate, this.model.toJSON()) …
50. Optimization
Once you finish writing your project, simply run a utility
called r.js (part of RequireJS) on your main script
r.js is a node executable script
It will turn all of your modules into one single, minified file
Creating an application manifest is required
node r.js
JS
JS min
JS
JS JS