writing html5 mobile web apps using backbone.js

Post on 06-May-2015

40.002 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

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.

TRANSCRIPT

Writing HTML5 Mobile Web Apps

A complete development stackRon Reiter (Any.DO)

Agenda

HTML5 or native?

HTML5 Mobile Development FrameworksPhoneGap

Trigger.IO

UI FrameworksjQuery Mobile

Sencha Touch

jqMobi

MVC with Backbone.js

Client Side Templating with Mustache

Modular Javascript with RequireJS

Go web or native?

Web Native

Cross-platform code. Smoother user interface.

CSS3 is very powerful, easy and flexible compared to Android and iPhone UI libraries.

More control and flexibility (for example, PhoneGap does not export all native abilities).

Easy to patch / update because only web assets need to be replaced.

You will need to write Javascript to 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.

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

Mobile Development Frameworks

PhoneGap, Trigger.IO

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

PhoneGap APIs

Accelerometer

Camera

Capture

Compass

Connection

Contacts

Device

Events

File

Geolocation

Media

Notification

Storage

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!

Trigger.IO

UI FrameworksjQuery Mobile, Sencha Touch, jqMobi

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 communityhttp://jquerymobile.com/

Sencha Touch – Commercial, robusthttp://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

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

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

jQuery Mobile Features

Pages and sliding page transitions, toolbars (header, footer, fixed), navigation pane, forms, themes and more

Codiqa – Rapid jQuery Mobile Prototyping

MVC Frameworks

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

Backbone.js

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

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

Code with Backbone

Code without Backbone Code with Backbonefunction createListView(id) {

var listView = $(“<div>”).addClass(“list”) .click(function(e) { if ($(e).is(“li”)) $(e.target).addClass(“selected”); $(this).data(“selected”, $(e.target) .text());}).keypress(function(e) { if (e.keyCode == 8) { $(this).find(“.selected”).remove(); });

return listView;}

var listView = createListView();

Var ListView = Backbone.View.extend({ tagName: “div”, className: “list”, events: { “click li” : “clickItem”, “keypress” : “deleteOnKeypress” }, clickItem: function(e) { $(e.target).addClass(“selected”); this.selected = $(e.target).text(); }, deleteOnKeypress: function(e) { if (e.keyCode == 8) { $(this.el).find(“.selected”).remove(); } }}

var listView = new ListView();

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 operationsCollection Operations

HTTP GET = Read

HTTP POST = Create

Model OperationsHTTP PUT = Update

HTTP DELETE = Delete

Backbone MVC Architecture

ViewHTML + CSS

ControllerBackbone.View

ModelBackbone.Model

DOM ManipulationWith jQuery andtemplating

DOM View Events

Backbone REST Sync

Server Model Database

Model Events

Model updatedaccording touser interaction

Backbone Model

Model Viewchange/delete

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)

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

Backbone Model

Model

task.save({ title: “Get Rich”, done: false});

Viewchange:title

Server

HTTP PUT /tasks/1

Backbone Model

Model

task.destroy()

Viewdestroy

remove

Server

HTTP DELETE /tasks/1

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

Model

Collection Server

Backbone Collection

Backbone collections can fetch a collection from the server

A “reset” event is fired when results from the server return

Collection Server

tasks.fetch();tasks.bind(“reset”, this.addTaskViews);

HTTP GET /tasks

Model

Model

Model

Backbone Collection

Backbone collections have the “create” method, which creates a new model

Model

Model

Model

Collection Server

New Model

tasks.create({ title: “Hello, world!”, done: false});tasks.bind(“add”, this.addTaskView)

HTTP POST /tasks

New task ID: 3

New Model

Summary - Backbone REST Architecture

ModelView

ModelView

ModelView

ModelView

Collection

PUT /tasks/41DELETE /tasks/41

PUT /tasks/39DELETE /tasks/39

PUT /tasks/40DELETE /tasks/40

PUT /tasks/38DELETE /tasks/38

GET /tasksPOST /tasks

Collection OperationsModel Operations

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({ tagName : “div”, className: “section”})

Backbone.View.extend({ el: $(“#main-view”);})…<div id=“main-view”></div>

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

Backbone View

Let’s create a todo item view, which represents a single todo item in a todo list

View

var todoItemView = Backbone.View.extend({ tagName: “div”, className: “todo”});

Backbone View

Now let’s add the model it is bound to

var todoItemView = Backbone.View.extend({ tagName: “div”, className: “todo”, model: todoModel});

View

Model

Backbone View

Get notified when the model is changed by binding on model change events, so we’ll know we need to update itvar todoItemView = Backbone.View.extend({

tagName: “div”, className: “todo”, model: todoModel, initialize: function() { _.bindAll(this, “update”); this.model.bind(“change”, this.update); }});

View

Model

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() { _.bindAll(this, “update”, “check”); this.model.bind(“change”, this.update); }, events: { “change .done-checkbox” : this.check }});

View

Model

X

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() { _.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

Model

X

Backbone View

Let’s update the view when we receive the “update” eventvar todoItemView = Backbone.View.extend({

tagName: “div”, className: “todo”, model: todoModel, initialize: function() { _.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”); }); }, update: function() { this.title.text(this.model.get(“title”)); if (this.checkbox.val()) { $(this.el).addClass(“checked”); } else { $(this.el).removeClass(“checked”); }}});

View

Model

X

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 ways1. 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

{{ 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

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).

Backbone.View.extend({ render: function() { $(this.el).html( Mustache.render(todoItemTemplate, this.model.toJSON())); });

View

Template

Model

Mustache

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.

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

RequireJS

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

How to use RequireJS

Boilerplate code examplehttps://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.

Code with RequireJS

Code without Require.JS Code with Require.JS<script src=“foo1.js”></script><script src=“foo2.js”></script><script src=“foo3.js”></script><script src=“foo4.js”></script><script> foo1.do(); foo2.do(); foo3.do(); foo4.do();</script>

<script src=“require.js”></script><script>require([“foo1”, “foo2”, “foo3”, “foo4”],function(foo1, foo2, foo3, foo4) { foo1.do(); foo2.do(); foo3.do(); foo4.do();});</script>

foo4.js:// hmmm. Can I use foo1, foo2, and foo3?// let’s put foo4 as a global variable.window.foo4 = …

foo4.js:define([“foo1”, “foo2”, “foo3”], function(foo1, foo2, foo3) { var foo4 = … return foo4;});

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()) …

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

JSJS

JSJS

minJS

node r.js

Thank You!

Questions?

top related