This was presented during the workshop on the topic. The complete code of the app that was created during the workshop is available at Github https://github.com/mathurakshay/explore-venues
2. Akshay Mathur
• Founding Team Member of
– ShopSocially (Enabling “social” for retailers)
– AirTight Neworks (Global leader of WIPS)
• 15+ years in IT industry
– Currently Principal Architect at ShopSocially
– Mostly worked with Startups
• From Conceptualization to Stabilization
• At different functions i.e. development, testing, release
• With multiple technologies
@akshaymathu
2
3. What have we learnt
• Creating basic web pages
– HTML tags
– CSS
• Basic JavaScript and jQuery
–
–
–
–
Reading and writing DOM
Getting data using AJAX calls
Responding to browser events
jQuery templates
• CoffeeScript
• Object Oriented JavaScript
– JS Classes
– Extending classes using prototypes
4. BackboneJS
• Provides MVC structure for JavaScript
• Built on top of UnderscoreJS
• Other than Model, View and Controller
(Router) also provides Event and Collection
objects
– Using custom events help writing good code and
eliminates use of global variables
– Array of Models with same structure can be
combined into Collection for ease of handling
@akshaymathu
4
5. UnderscoreJS
• Has nothing to do with MVC
• Provides many useful functions on
– Arrays
– Objects
– Array of Objects
• BackboneJS directly extends a few functions
for its objects (Classes)
@akshaymathu
5
7. Backbone View
• A View is created by extending a Backbone’s
view class
• A View always have 2 properties:
– el: An HTML element that is in the root of the
View
– model: Model that powers data to the View
@akshaymathu
7
8. Creating View
class LoginView extends Backbone.View
initialize: =>
@template = $.template(
$(’#login_template’))
@render()
render: =>
$(@el).html $.tmpl(@template,
@model.toJSON())
class LoginController extends Backbone.Router
initialize: =>
@l_model = new LoginModel window.app_info
@l_view = new LoginView model: @l_model,
el: ’#login_div’
@akshaymathu
8
9. Rendering HTML
• Typically a view has a template
• In the render method, the template should be
filled with data and inserted into el
– The el can be attached to DOM before or after filling
HTML
class LoginView extends Backbone.View
initialize: =>
@template = $.template
$(’#login_template’)
render: =>
$(@el).html $.tmpl(@template,
@model.toJSON())
@akshaymathu
9
10. Browser Events
• Defining events object within a view
automatically connects functions to event
handlers
class LoginView extends Backbone.View
events:
'click #login_btn' : ’login_handler’
login_handler: (ev) =>
window.mpq_track ’Login Click’
@akshaymathu
10
12. Thinking of Views
• Create a view for whole page
– Base view that can handle anything as needed
– It may be rendered by server
• A view for each unit that is logically different
– Event handling is needed within
• Keep separate model for each view
@akshaymathu
12
13. Zombie Views
• When new views are created from a view class
and attached to DOM in a way that it replaces
HTML of an old view
– The old view object and its events remain attached
and create issues
$(“#button”).click ->
@view = new SomeView
Class SomeView extends backbone.View
render: =>
$(“container”).html template_html
@akshaymathu
13
14. Handling Zombies
• Don’t let zombies create
• Use .destroy() on the View instance
• Cleanup associated model if needed
$(“#button”).click ->
@view = new SomeView
$(“#close_button”).click ->
@view.destroy()
@akshaymathu
14
16. Backbone Model
• Model is defined extending the Backbone’s
Model Class
• The Model object can be created with the
data coming from the server (database)
• The data can be read later using .get() and set
using .set() methods
• Transient data (not intended to be synced with
server) can be stored separately
@akshaymathu
16
17. Creating Model
app_info = {type: 4,
name: ‘Internal Application’,
protected: true
}
class LoginModel extends Backbone.Model
initialize: =>
@is_changed = false
class LoginRouter extends Backbone.Router
initialize: =>
@l_model = new LoginModel app_info
@akshaymathu
17
19. Model Events
• Model object raises events on change in data
– changed
– remove
• These events may be captured (by view) and
acted upon accordingly
– A few properties are also set within the Model
– Old and new values of the Model are also
available
@akshaymathu
19
20. Keeping UI Up-to-Date
class LoginView extends Backbone.View
initialize: =>
@model.bind(‘change’, @render)
@render()
render: =>
$(@el).html $.tmpl(@template,
@model.toJSON())
class LoginRouter extends Backbone.Router
initialize: =>
@l_model = new LoginModel app_info
@l_view = new LoginView model:@l_model
@akshaymathu
20
21. Syncing with Server
• For having better control over data, one
should collect data from the Model and make
an AJAX call
• One can also attach a URL to the Model and
RESTful AJAX calls are automatically done
@akshaymathu
21
22. Collections
• Simple data structure for storing many
instances of same model
– Array of Model objects
• Provides methods and properties for
managing the list
• Can be created by extending Collection class
of Backbone
@akshaymathu
22
23. Creating Collection
class VenueModel extends Backbone.Model
class VenueCollection extends Backbone.Collection
model: VenueModel
class VenueListModel extends Backbone.Model
initialize: =>
@e_list = new VenueCollection
class VenueListView extends Backbone.View
initialize: =>
@model.e_list.bind('add', @add_venue)
add_venue: (venue_model) =>
@akshaymathu
23
25. Backbone Router
• It routes URLs to respective methods
• A Router is created by extending a Backbone’s
router class
• Route configuration can be passed while
creating the router object instance
@akshaymathu
25
26. Creating Router
class LoginController extends Backbone.Router
initialize: =>
@l_model = new LoginModel window.app_info
@l_view = new LoginView model: model, el:
’#login_div’
routes:
“help”: “help”
$(document).ready ->
l_router = new LoginController()
@akshaymathu
26
27. Route Configuration
• Rout configuration is a JavaScript object
mapping URLs to functions
– URL patterns may be used as key
– Data can be read from URLs and passed to
functions as parameters
@akshaymathu
27
29. Catch All
• Router is sometimes used for putting methods
not belonging to any other Model or View
• Router also acts as a glue for all other objects
– Typically all basic views are initialized in router so
any cross-view functionality can be implemented
in router
@akshaymathu
29
31. Events
• Events facilitate communication amongst
different objects
– Data can be passed along with events
• Browser raises events on user actions
• Publish-Subscribe architecture avoids tight
coupling between objects
@akshaymathu
31
32. Backbone Events
• Backbone objects also raise events on various
actions
– add: when a model is added to a collection.
– remove: when a model is removed from a collection.
– reset: when the collection's entire contents have
been replaced.
– change: when a model's attributes have changed.
– change: when a specific attribute has been updated.
– destroy: when a model is destroyed.
@akshaymathu
32
33. Custom Events
• Backbone’s event module can be mixed with
an object
– The the objects gets the ability to raise events
programmatically
– The object also gets the ability to listen to the
events
@akshaymathu
33
39. Design Views
• Page view
– Accordion
– Google Map
• Venue list view
– All venue tiles
• Venue view
– Single venue tile
• Venue details view (do later)
– Popup with details of the venue
@akshaymathu
39
40. Design Models
• As a thumb rule, a model can be kept for each
view
– Page model
– Venue list model
– Venue model
– Venue details model (do later)
@akshaymathu
40
41. Create Base HTML
• Head
– Include Bootstrap CSS
– Include JS
• Google Map API, jQuery’s , jQuery template
• Bootstrap, Underscore, Backbone, App’s custom
• Top bar
– Use navbar’s HTML from Bootstrap
• Accordion
– Use Bootstrap jQuery plugin’s HTML
– Create accordion headers
– Keep accordion bodies blank
@akshaymathu
41
42. Create jQuery Templates
• No template for Google Map
– Map UI is completely rendered by Google APIs
• Venue template
– Each venue tile
• Venue details template (do later)
– Venue details popup
– Use Bootstrap modal jQuery plugin’s HTML
@akshaymathu
42
45. Basic Skeleton
class VenueModel extends Backbone.Model
class VenueCollection extends Backbone.Collection
model: VenueModel
class VenueListModel extends Backbone.Model
initialize: =>
@e_list = new VenueCollection
class VenueListView extends Backbone.View
initialize: =>
@model.e_list.bind('add', @add_venue)
class VenueView extends Backbone.View
class PageModel extends Backbone.Model
class PageView extends Backbone.View
class VenueController extends Backbone.Router
@akshaymathu
45
46. Start Execution
• On DOM ready event, instantiate the router
$(document).ready ->
venue_controller = new VenueController
• Create an instance of page model and view in initialize
routine of router
class VenueController extends
Backbone.Router
initialize: =>
@page_model = new PageModel
@page_view = new PageView (
el: $("#maindiv"),
model: @page_model)
@akshaymathu
46
47. Initialize Page View
• Page view initializes automatically when its
instance gets created in router
• Initialize venue list
class PageView extends Backbone.View
initialize: =>
@venue_list_model = new VenueListModel
@venue_list_view = new VenueListView(
el: $("#venue_list"),
model: @venue_list_model
)
@akshaymathu
47
48. Google Map
• In page view, create Google Map object and render it in the div
created for that
• Register event handler for Google Map click event
@map = new google.maps.Map(
$(’#map-canvas’)[0]),
map_options)
google.maps.event.addListener @map,
'click', (ev) =>
@get_venues(
ev.latLng.lat(),
ev.latLng.lng())
@akshaymathu
48
49. Get Venues
• Make a JSONP AJAX call to FourSquare for getting
venues near the clicked location
• Create a model from each venue in result and
add to collection
venue_model = new VenueModel
item.venue
@venue_list_model.e_list.add
venue_model
@akshaymathu
49
50. Render Venue Tile
• As venue model adds into collection, the add event
handler on collection is fired in venue list view
@model.e_list.bind('add',
@add_venue)
• Handlers gets the venue view rendered and attaches it
to the DOM
add_venue: (venue_model) =>
venue_view = new VenueView(
model: venue_model)
tile_html = venue_view.render()
$("#venue_col).append tile_html
@akshaymathu
50
51. Click on Venue Tile
• Venue view registers click handler by defining event
map
class VenueView extends
Backbone.View
events:
"click" : 'show_details’
• Venue detail popup is to be shown outside base
element (el) of the venue view so it raises an event
show_details: =>
ED.trigger ED.SHOW_VENUE, @model
@akshaymathu
51
52. Showing Details Popup
• Page view listens to the event and renders
details popup
class PageView extends Backbone.View
initialize: =>
ED.bind ED.SHOW_VENUE, @show_popup
show_popup: (venue_model) =>
@detail_view = new VenueDetailView
model: venue_model
$(@el).append @detail_view.render()
@akshaymathu
52
54. Optimization
• Venue model and Venue detail model
represent exactly same entity
– There is always 1-1 relation
• Same model may be used for both
– First render should not be slow for bringing details
@akshaymathu
54