developing maintainable cordova applications
DESCRIPTION
Slides of a talk of a seminars series I gave at WebRatio in January 2014. I implemented many best practices and advices in this presentation in a generic app template available here: https://github.com/iivanoo/cordovaboilerplateTRANSCRIPT
![Page 1: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/1.jpg)
DISIM | University of L’Aquila
Ivano Malavolta
Developing maintainable Cordova applications
![Page 2: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/2.jpg)
Roadmap
• Introduction
• Backbone
• Require JS
• Handlebars
• Conclusions
I implemented all best practices and advices in this presentation in a generic app template available here:
https://github.com/iivanoo/cordovaboilerplate
![Page 3: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/3.jpg)
Introduction
We are building apps, not web sites
If your code is not structured:
• it is extremely easy that your web app becomes a
big mess of HTML + CSS + JavaScript
• maintaining each part of your app asks for a
deep analysis of ALL its aspects (logic, presentation, etc.)
• you may waste a whole day due to a missing <
![Page 4: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/4.jpg)
What we want to avoid
Imagine yourself trying to change
• how a movie should be rendered in your app
• the REST API providing info about movies
![Page 5: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/5.jpg)
Some technical advices from a real project...
![Page 6: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/6.jpg)
Some technical advices from a real project...
![Page 7: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/7.jpg)
Some technical advices from a real project...
![Page 8: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/8.jpg)
Some technical advices from a real project...
![Page 9: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/9.jpg)
Some technical advices from a real project...
![Page 10: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/10.jpg)
How I structure my applications
MVC framework for giving structure
File and module loader for code modularization
Templating engine for separation of concerns
Disclaimer this is MY way to structure apps, you can follow yours
![Page 11: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/11.jpg)
How I structure my applications
![Page 12: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/12.jpg)
Backbone
• Why Backbone
• Events
• Models
• Collections
• Views
• Routers
• Summary
![Page 13: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/13.jpg)
Why Backbone
Backbone gives you STRUCTURE
![Page 14: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/14.jpg)
Why Backbone
From the Backbone website...
manipulate the DOM
lists of models
represent data
![Page 15: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/15.jpg)
Why Backbone
Additionally, Backbone provides also features for:
sync
for managing how to persist models (default is via REST)
events
for managing how data and control are exchanged within your app
router
for managing the interaction flow among views
![Page 16: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/16.jpg)
Who is using Backbone?
![Page 17: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/17.jpg)
Backbone
• Why Backbone
• Events
• Models
• Collections
• Views
• Routers
• Summary
![Page 18: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/18.jpg)
Events
Any object communicates with other objects via events
It gives the object the ability to bind and trigger custom named events
It is extremely useful for exchanging data and control among objects
![Page 19: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/19.jpg)
Events
Basically, each object can:
• listen to events
• trigger events
![Page 20: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/20.jpg)
Events
Two types of events:
you define your own types of event
built-in
custom
![Page 21: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/21.jpg)
Events API
object will react to the “alert” event (the “off” function detaches the event)
event parameters
the “alert” event is fired
![Page 22: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/22.jpg)
Events API
Events methods:
on
object.on(event, callback, [context])
off
object.off([event], [callback], [context])
once
object.once(event, callback, [context])
trigger
object.trigger(event, [*args])
listenTo
object.listenTo(other, event, callback)
stopListening
object.stopListening([other], [event], [callback])
listenToOnce
object.listenToOnce(other, event, callback)
![Page 23: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/23.jpg)
Events summary
![Page 24: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/24.jpg)
Backbone
• Why Backbone
• Events
• Models
• Collections
• Views
• Routers
• Summary
![Page 25: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/25.jpg)
Models
Models represent your data
Each model represents a data type in your app, together with the logic surrounding it, like:
• persistence
• conversions
• validation
• computed properties
• access control
MVC: Notify their observers about state using the Observer pattern
![Page 26: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/26.jpg)
Models
You extend Backbone.Model with your domain-specific methods, and Model provides a basic set of functionality for managing changes, like:
• getter and setter
• id
• constructor
• REST-based persistence
![Page 27: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/27.jpg)
Example of model
custom method
setting an attribute
event fired when “color” changes
custom method invocation
![Page 28: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/28.jpg)
Model constructore and attributes
initialize()
it is triggered every time you create a new instance of a model
it works also for collections and views
it can take a JS object for setting also attributes
get() & set()
they are used to set and retrieve the value of certain attributes
defaults
a property named 'defaults' in your model declaration
![Page 29: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/29.jpg)
Example
http://goo.gl/UOahsP
![Page 30: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/30.jpg)
Model persistence
Backbone.sync
is the function that Backbone calls every time it attempts to read or save a model
By default, it uses Ajax to make a REST-ish request to a server
Resources represented as JSON strings
![Page 31: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/31.jpg)
Sync signature
sync(method, model, [options])
method
the CRUD method ("create“, "read“, "update", or "delete")
model
the model (or collection) to be synced
options
success and error callbacks, and all other jQuery request options
example of overriden sync: http://bit.ly/KWdxNN
Sync returns a jQuery XMLHttpRequest (jqXHR) object It implements the Promise interface
![Page 32: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/32.jpg)
Sync usage
Normally you will not use the sync method directly, you will do it implicitly when you call one of these methods
Model
• fetch: gets the most up-to-date values of the model instance
• save: persists the model instance
• destroy: deletes the model instance
Collection
• fetch: gets all the models of the collection from the server
• create: creates a model, saves it to the server and adds it to the collection
![Page 33: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/33.jpg)
Overriding sync
You can override it in order to use a different persistence strategy, such as:
• WebSockets
• Local Storage
• WebSQL
Backbone.sync is the default global function that all models use unless the models have a sync method specifically set
![Page 34: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/34.jpg)
Models summary
![Page 35: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/35.jpg)
Backbone
• Why Backbone
• Events
• Models
• Collections
• Views
• Routers
• Summary
![Page 36: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/36.jpg)
Collections
Collections are ordered sets of models
You can:
• bind change events to be notified when any model in the collection has been modified
• listen for add and remove events
• fetch the collection from the server (or other persistence layers)
• find models or filter collections themeselves
The model attribute of a collection represents the kind of model that can be stored in it
Any event that is triggered on a model in a collection will also be triggered on the collection directly
MVC: Notify their observers about state using the Observer pattern (same as models)
![Page 37: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/37.jpg)
Collection example
http://goo.gl/UOahsP
![Page 38: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/38.jpg)
Collections summary
![Page 39: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/39.jpg)
Backbone
• Why Backbone
• Events
• Models
• Collections
• Views
• Routers
• Summary
![Page 40: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/40.jpg)
Views
Views represent and manage the visible parts of your application
They are also used to
• listen to interaction events
• and react accordingly
views can be rendered at any time, and inserted into the DOM
you get high-performance UI rendering with as few reflows and repaints as possible
MVC: observe models, and update itself according to the state of the models + manage user inputs (it’s a controller, to this sense)
![Page 41: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/41.jpg)
Interaction with the DOM
All views refer to a DOM element at all times, even if they are already in the page or not
this.el is a reference to the DOM element, it is created from:
tagName
for example body, ul, span, img
className
class name of some element within the DOM
id
id of an element within the DOM
If none of them is specified, this.el is an empty <div>
![Page 42: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/42.jpg)
Rendering the view
The render() method is used to update the this.el element with the new HTML
The default implementation of render() is a no-op
you have to override it to update this.el with your HTML code
Backbone is agnostic with respect to your code in render(), however...
you are STRONGLY encouraged to use a Javascript templating library here
![Page 43: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/43.jpg)
View example
http://goo.gl/UOahsP
![Page 44: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/44.jpg)
Interaction with the user
Events map “event_name selector”: callback
Events callbacks
![Page 45: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/45.jpg)
Views summary
![Page 46: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/46.jpg)
Backbone
• Why Backbone
• Events
• Models
• Collections
• Views
• Routers
• Summary
![Page 47: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/47.jpg)
The router
Backbone.Router provides methods for routing client-side pages,
and connecting them to actions and events
At a minimum, a router is composed of two main parts:
routes
an hash that pairs routes to actions
actions
JS functions triggered when certain routes are navigated
![Page 48: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/48.jpg)
Routing
Every router contains an hash that maps routes to functions on your router
URLs fragments can also contain dynamic data via Backbone-specific URL parts:
parameter (:param)
match a single URL component between slashes
splat (*fragment)
match any number of URL components
![Page 49: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/49.jpg)
Routing
routes map
routing functions
![Page 50: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/50.jpg)
History
History serves as a global router to
1. handle hashchange events
2. match the appropriate route
3. trigger callbacks
You should never access it directly, you just need call Backbone.history.start() to begin monitoring hashchange events, and dispatching routes in your app
Call Backbone.history.navigate(ROUTE_NAME, {trigger: true}); to activate a specific route of the router
Technically, it uses the HTML5 History API to listen to to its job
For older browsers, it uses URL hash
fragments as fallback
![Page 51: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/51.jpg)
Router summary
![Page 52: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/52.jpg)
Backbone
• Why Backbone
• Events
• Models
• Collections
• Views
• Routers
• Summary
![Page 53: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/53.jpg)
Classical workflow
1. You dig into JSON objects
2. Look up elements in the DOM
3. Update the HTML by hand
![Page 54: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/54.jpg)
Backbone-based workflow
• You organize your interface into logical views backed by models
• Each view can be updated independently when the model changes, without having to redraw the page
You can bind your view‘s render() function to the model‘s "change” event now everywhere that model data is displayed in the UI, it is always immediately up to date
![Page 55: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/55.jpg)
Is Backbone real MVC?
Let’s look at the description of the Model-View-Presenter pattern on Wikipedia:
an interface defining the data to be displayed or otherwise acted upon in the user interface
passive interface that displays data (the model) and routes user commands (events) to the presenter to act upon that data
acts upon the model and the view. It retrieves data from repositories (the model), and formats it for display in the view
Model
View
Presenter
![Page 56: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/56.jpg)
Roadmap
• Introduction
• Backbone
• Require JS
• Handlebars
• Conclusions
![Page 57: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/57.jpg)
Require JS
• Why Require JS
• Using modules
• Defining modules
• Configuring Require JS
![Page 58: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/58.jpg)
Why Require JS
We are building apps, not website
We need well-specified and isolated JS files/modules
Code complexity grows as the app gets bigger
we need some sort of #include/import/require
ability to load nested dependencies
![Page 59: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/59.jpg)
What we want to avoid
uncontrolled scripts
poor control flow understanding
![Page 60: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/60.jpg)
Require JS
RequireJS is a JavaScript file and module loader
Using a modular script loader like Require JS will improve the modularity of your code
speed in implementing changes
better undestanding of the code
Require JS allows modules to be loaded as fast as possible, even out of order, but evaluated in the correct dependency order
Built on the Module Pattern
JavaScript file and module loader
![Page 61: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/61.jpg)
The module pattern
A JavaScript code module is some JavaScript code located in a registered location (e.g., a function)
All of the code that runs inside the function lives in a closure, which provides
• privacy
• state
throughout the lifetime of the module
![Page 62: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/62.jpg)
Module example
Technically, it is simply a function that executes immediately
![Page 63: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/63.jpg)
Module VS script files
A module is different from a traditional script file in that it defines a well-scoped object that avoids polluting the global namespace its retained objects can be deleted by the GC
It can explicitly list its dependencies and get a handle on those dependencies without needing to refer to global objects, but instead receive the dependencies as arguments to the function that defines the module
VS
![Page 64: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/64.jpg)
Require JS
• Why Require JS
• Using modules
• Defining modules
• Configuring Require JS
![Page 65: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/65.jpg)
Using modules
main.js is the entry point of the app
The main HTML:
![Page 66: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/66.jpg)
The main JS file:
Using modules
This function is called when all dependencies are loaded If a required module calls define(), then this function is not fired until its dependencies have been loaded
Required modules References to required modules
![Page 67: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/67.jpg)
Require JS
• Why Require JS
• Using modules
• Defining modules
• Configuring Require JS
![Page 68: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/68.jpg)
Module without dependencies Always one module per files
Public variables
Setup code
the simplest module can be a plain collection of name/value pairs
module with initialization
The returned element can be any valid JS element By convention I always return an object representing the module
![Page 69: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/69.jpg)
Module with dependencies
Dependency definition
Dependent module reference
Dependent module usage
This function is called when zepto.js is loaded.
If zepto.js calls define(), then this function is not fired until also zepto’s dependencies have loaded
![Page 70: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/70.jpg)
Require JS under the hoods...
1. loads each dependency as a script tag, using head.appendChild() and waits for all dependencies to load
2. computes the right order in which to call the functions that define the modules
3. calls the module definition functions of each dependency in the right order
main.js
jQuery Backbone
SpinJS
MoviesCollection
MovieModel
MoviesView
1
2
3 4
5
6 7
![Page 71: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/71.jpg)
Require JS
• Why Require JS
• Using modules
• Defining modules
• Configuring Require JS
![Page 72: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/72.jpg)
Configuring Require JS
Require refers to a global configuration options
It allows developers to:
• set the paths to all used frameworks in one place
• use older frameworks as modules (shim)
• define configuration params for the modules
• etc.
![Page 73: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/73.jpg)
Configuring Require JS
Shims for older frameworks
paths to used frameworks
Dependent module usage
![Page 74: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/74.jpg)
Roadmap
• Introduction
• Backbone
• Require JS
• Handlebars
• Conclusions
![Page 75: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/75.jpg)
Handlebars
• Why Handlebars
• Handlebars basics
• Usage with Backbone and Require JS
![Page 76: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/76.jpg)
Why Handlebars
We want to separate presentation from logic
TRANSLATE TO: we don’t want to put any HTML element into JavaScript code
separate logic from presentation
Imagine yourself trying to change how a movie should be rendered in your app...
![Page 77: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/77.jpg)
Handlebars
• Why Handlebars
• Handlebars basics
• Usage with Backbone and Require JS
![Page 78: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/78.jpg)
Example of template
A handlebars expression is
{{ something }}
![Page 79: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/79.jpg)
Escape values
Handlebars HTML-escapes all the values returned by an {{expression}} If you don't want Handlebars to escape a value, use the "triple-stash“ {{{ expression }}}
![Page 80: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/80.jpg)
Populate your template
The recurrent process of obtaining a populated template is the following:
1. create the template T with its placeholders {{ - }}
2. compile the template into a JavaScript function t
3. create a context CT containing the actual values for placeholders
4. run the compiled template t(CT) to obtain the final HTML fragment
![Page 81: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/81.jpg)
1. create the template
Templates are defined within a <script> tag or in external files
![Page 82: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/82.jpg)
2. compile the template
Handlebars.compile is used to compile a template
Compiling = obtaining a JS object representing the template
![Page 83: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/83.jpg)
3. create a context for the template
A context is a Javascript object used to populate a template
Here the keys of the object must match with the name of the placeholder to be populated
![Page 84: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/84.jpg)
4. obtain the final HTML fragment
You have to execute a template with a context in order to get its corresponding HTML code
![Page 85: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/85.jpg)
Expressions
The simplest expression is a simple identifier
This expression means "look up the username property in the current context"
![Page 86: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/86.jpg)
Expressions with paths
Handlebars expressions can also be dot-separated paths
This expression means
"look up the user property in the current context,
then look up the username property in the result"
![Page 87: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/87.jpg)
Helpers
Helpers are Javascript functions that return HTML code
You should return a Handlebars SafeString if you don't want it to be escaped by default
![Page 88: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/88.jpg)
Calling helpers
A Handlebars helper call is a simple identifier, followed by zero or more parameters
Each parameter is a Handlebars expression
es.
{{ test user }}
In this case, test is the name of the Handlebars helper, and user is a parameter to the helper
![Page 89: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/89.jpg)
Built-in helpers
It shifts the context for a section of a template
with
<div class="entry“> <h1>{{title}}</h1> {{#with author}} <h2>By {{firstName}} {{lastName}}</h2> {{/with}} </div>
{ title: "My first post!", author: { firstName: “Ivano", lastName: “Malavolta" } }
<div class="entry“> <h1>My first post!</h1> <h2>By Ivano Malavolta</h2> </div>
![Page 90: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/90.jpg)
Built-in helpers
To iterate over a list
each
Inside the block, you can use this
to reference the element being iterated
<ul class="people_list"> {{#each people}} <li>{{this}}</li> {{/each}} </ul>
{ people: [ “Ivano", “Andrea", “Paolo" ] }
<ul class="people_list"> <li>Ivano</li> <li>Andrea</li> <li>Paolo</li> </ul>
![Page 91: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/91.jpg)
Built-in helpers
It renders the block if its argument is not equal to false, undefined, null, []
If / Else
The unless helper is the inverse of if
<div class="entry“> <h1>{{title}}</h1> {{#if author}} <h2>By {{firstName}} {{lastName}}</h2> {{#else}} <h2>Unknown author</h1> {{/if}} </div>
{ title: "My first post!", author: undefined } }
<div class="entry“> <h1>My first post!</h1> <h2>Unknown author</h2> </div>
![Page 92: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/92.jpg)
handlebars summary
Each Template can contain Expressions and Helpers operating on them The main helpers are: • with • each • if / else /unless You can define your own Helpers that operate on expressions, they return HTML code A template can be (pre)-compiled and must be executed with a context in order to return the final HTML fragment
![Page 93: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/93.jpg)
Handlebars
• Why Handlebars
• Handlebars basics
• Usage with Backbone and Require JS
![Page 94: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/94.jpg)
Usage with Backbone and Require JS
Templates can be seen as special modules
So we can have the following:
• a separate HTML file for each template
• a Backbone view can have a dependency to each template
• the template can be executed by using a JSON object of the Backbone model as context
![Page 95: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/95.jpg)
Example
Dependency to template HTML file
It contains a string
Compiled template
Execution of the template
![Page 96: Developing maintainable Cordova applications](https://reader033.vdocuments.mx/reader033/viewer/2022060107/554af4c3b4c905fc0e8b4805/html5/thumbnails/96.jpg)
References
http://backbonejs.org http://requirejs.org
http://handlebarsjs.com https://github.com/iivanoo/cordovaboilerplate