SlideShare a Scribd company logo
@markbates
hire me*	

(for rent, not sale)
www.metacasts.tv

KODIO13
AngularJS vs. Ember vs. Backbone.js
Knockout.js
philosophies
Backbone.js
“minimal set of data-structure and view primitives 	

for building web application with JavaScript”
Backbone.js
do what you want, 	

however you want to do it	

(we won’t tell anyone)
Ember
“framework for creating ambitious web applications”
Ember
convention over configuration
AngularJS
“Toolset for building the framework most suited to your
application development”
AngularJS
plain old JavaScript
Round	

1
weight
“production” versions (minified)	

w/ required dependencies
AngularJS
base

templating language

data adapter

support

Ember

Backbone.js

81kb

235kb

6.4kb

built-in

73kb	

(handlebars)

??

built-in

210kb	

(ember-data)

32kb	

(jQuery)

N/A

32kb	

(jQuery)

17kb	

(json2.js)	

4.9kb	

(underscore.js)

81kb

550kb

60.3kb
Round	

2
“basic” models
Backbone.js
class	
  App.Beer	
  extends	
  Backbone.Model	
  
	
  	
  
class	
  App.Beers	
  extends	
  Backbone.Collection	
  
!

	
  model:	
  Beer
Ember
App.Beer	
  =	
  DS.Model.extend	
  
	
  	
  title:	
  DS.attr("string")	
  
	
  	
  abv:	
  DS.attr("number")	
  
	
  	
  country_id:	
  DS.attr("number")	
  
	
  	
  brewery_id:	
  DS.attr("number")	
  
	
  	
  brewery:	
  DS.belongsTo("App.Brewery")	
  
	
  	
  country:	
  DS.belongsTo("App.Country")
AngularJS

App.Beer	
  =	
  {}
“remote” models
Backbone.js
class	
  App.Beer	
  extends	
  Backbone.Model	
  
	
  	
  urlRoot:	
  "/api/v1/beers"	
  
	
  	
  	
  
class	
  App.Beers	
  extends	
  Backbone.Collection	
  
	
  	
  
	
  	
  url:	
  -­‐>	
  
	
  	
  	
  	
  if	
  @brewery_id?	
  
	
  	
  	
  	
  	
  	
  return	
  "/api/v1/breweries/#{@brewery_id}/beers"	
  
	
  	
  	
  	
  else	
  
	
  	
  	
  	
  	
  	
  return	
  "/api/v1/beers"	
  
	
  	
  
	
  	
  model:	
  Beer
Ember
App.Beer	
  =	
  DS.Model.extend	
  
	
  	
  title:	
  DS.attr("string")	
  
	
  	
  abv:	
  DS.attr("number")	
  
	
  	
  country_id:	
  DS.attr("number")	
  
	
  	
  brewery_id:	
  DS.attr("number")	
  
	
  	
  brewery:	
  DS.belongsTo("App.Brewery")	
  
	
  	
  country:	
  DS.belongsTo("App.Country")
Ember
DS.RESTAdapter.reopen	
  
	
  	
  namespace:	
  'api/v1'	
  
	
  	
  
App.Store	
  =	
  DS.Store.extend	
  
	
  	
  revision:	
  11	
  
	
  	
  adapter:	
  DS.RESTAdapter.create()
AngularJS
App.factory	
  "Beer",	
  ($resource)	
  -­‐>	
  
	
  	
  return	
  $resource	
  "/api/v1/beers/:id",	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {id:	
  "@id"},	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {update:	
  {method:	
  "PUT"}}
Round	

3
routers
Backbone.js
@Router	
  =	
  Backbone.Router.extend	
  
	
  	
  
	
  	
  initialize:	
  -­‐>	
  
	
  	
  	
  	
  @countries	
  =	
  new	
  Countries()	
  
	
  	
  
	
  	
  routes:	
  
	
  	
  	
  	
  "breweries/:brewery_id":	
  "brewery"	
  
	
  	
  	
  	
  "breweries/:brewery_id/edit":	
  "breweryEdit"	
  
	
  	
  
	
  	
  brewery:	
  (brewery_id)	
  -­‐>	
  
	
  	
  	
  	
  @changeView(new	
  BreweryView(collection:	
  @countries,	
  model:	
  new	
  Brewery(id:	
  brewery_id)))	
  
	
  	
  
	
  	
  breweryEdit:	
  (brewery_id)	
  -­‐>	
  
	
  	
  	
  	
  @changeView(new	
  BreweryEditView(collection:	
  @countries,	
  model:	
  new	
  Brewery(id:	
  brewery_id)))	
  
	
  	
  
	
  	
  changeView:	
  (view)	
  =>	
  
	
  	
  	
  	
  @currentView?.remove()	
  
	
  	
  	
  	
  @currentView	
  =	
  view	
  
	
  	
  	
  	
  $("#outlet").html(@currentView.el)
Ember
App.Router.map	
  -­‐>	
  
	
  	
  @resource	
  "brewery",	
  {path:	
  "brewery/:brewery_id"}
Ember

App.BreweryRoute	
  =	
  Ember.Route.extend	
  
	
  	
  model:	
  (params)-­‐>	
  
	
  	
  	
  	
  App.Brewery.find(params.brewery_id)
AngularJS
App.config	
  ($routeProvider)	
  -­‐>	
  
	
  	
  
	
  	
  $routeProvider	
  
	
  	
  	
  	
  .when("/breweries/:id",	
  {	
  
	
  	
  	
  	
  	
  	
  templateUrl:	
  "/assets/brewery.html",	
  
	
  	
  	
  	
  	
  	
  controller:	
  "BreweryController"	
  
	
  	
  	
  	
  })	
  
	
  	
  	
  	
  .when("/breweries/:id/edit",	
  {	
  
	
  	
  	
  	
  	
  	
  templateUrl:	
  "/assets/edit_brewery.html",	
  
	
  	
  	
  	
  	
  	
  controller:	
  "EditBreweryController"	
  
	
  	
  	
  	
  })
Round	

4
controllers/views
Backbone.js
class	
  @BreweryEditView	
  extends	
  Backbone.View	
  
	
  	
  
	
  	
  template:	
  "brewery_edit"	
  
	
  	
  
	
  	
  events:	
  
	
  	
  	
  	
  "click	
  #save-­‐button":	
  "saveClicked"	
  
	
  	
  	
  	
  "keypress	
  #brewery-­‐title":	
  "titleEdited"	
  
	
  	
  
	
  	
  initialize:	
  -­‐>	
  
	
  	
  	
  	
  super	
  
	
  	
  	
  	
  @countriesView	
  =	
  new	
  CountriesView(collection:	
  @collection)	
  
	
  	
  	
  	
  @$el.html(@countriesView.el)	
  
	
  	
  	
  	
  @model.on	
  "change",	
  @render	
  
	
  	
  	
  	
  @model.fetch()	
  
	
  	
  
	
  	
  render:	
  =>	
  
	
  	
  	
  	
  @$("#country-­‐outlet").html(@renderTemplate())	
  
	
  	
  	
  	
  return	
  @

	
  	
  saveClicked:	
  (e)	
  =>	
  
	
  	
  	
  	
  e?.preventDefault()	
  
	
  	
  	
  	
  attrs	
  =	
  
	
  	
  	
  	
  	
  	
  title:	
  @$("#brewery-­‐title").val()	
  
	
  	
  	
  	
  	
  	
  synonyms:	
  @$("#brewery-­‐synonyms").val()	
  
	
  	
  	
  	
  	
  	
  address:	
  @$("#brewery-­‐address").val()	
  
	
  	
  	
  	
  @model.save	
  attrs,	
  
	
  	
  	
  	
  	
  	
  success:	
  (model,	
  response,	
  options)	
  =>	
  
	
  	
  	
  	
  	
  	
  	
  	
  App.navigate("/breweries/#{@model.id}",	
  trigger:	
  true)	
  
	
  	
  	
  	
  	
  	
  error:	
  (model,	
  xhr,	
  options)	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  	
  	
  errors	
  =	
  []	
  
	
  	
  	
  	
  	
  	
  	
  	
  for	
  key,	
  value	
  of	
  xhr.responseJSON.errors	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  errors.push	
  "#{key}:	
  #{value.join(",	
  ")}"	
  
	
  	
  	
  	
  	
  	
  	
  	
  alert	
  errors.join("n")	
  
	
  	
  
	
  	
  titleEdited:	
  (e)	
  =>	
  
	
  	
  	
  	
  title	
  =	
  @$("#brewery-­‐title").val()	
  
	
  	
  	
  	
  @$("h2").text(title)	
  
!
	
  	
  #	
  further	
  code	
  omitted
Ember

App.BreweryController	
  =	
  Ember.ObjectController.extend	
  
	
  	
  
	
  save:	
  -­‐>	
  
	
  	
  	
  	
  @store.commit()	
  
	
  	
  
	
  	
  #	
  further	
  code	
  omitted
AngularJS
@EditBreweryController	
  =	
  ($scope,	
  $routeParams,	
  $location,	
  Brewery)	
  -­‐>	
  
	
  	
  
	
  	
  $scope.brewery	
  =	
  Brewery.get(id:	
  $routeParams.id)	
  
	
  	
  
	
  	
  $scope.save	
  =	
  -­‐>	
  
	
  	
  	
  	
  success	
  =	
  -­‐>	
  
	
  	
  	
  	
  	
  	
  $location.path("/breweries/#{$routeParams.id}")	
  
	
  	
  	
  	
  	
  	
  $scope.errors	
  =	
  null	
  
	
  	
  	
  	
  failure	
  =	
  (object)-­‐>	
  
	
  	
  	
  	
  	
  	
  $scope.errors	
  =	
  object.data.errors	
  
	
  	
  	
  	
  $scope.brewery.$update	
  {},	
  success,	
  failure
Round	

5
templates
Backbone.js
<h2><%=	
  @model.displayName()	
  %></h2>	
  
	
  	
  
<form>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  value='<%=	
  @model.get("title")	
  %>'id='brewery-­‐title'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  value='<%=	
  @model.get("synonyms")	
  %>'id='brewery-­‐synonyms'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="address">Address</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <textarea	
  class='input-­‐xxlarge'	
  id='brewery-­‐address'><%=	
  @model.get("address")	
  %></textarea>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <button	
  class='btn	
  btn-­‐primary'	
  id='save-­‐button'>Save</button>	
  
	
  	
  <a	
  href="/breweries/<%=	
  @model.id	
  %>"	
  class='btn'>Cancel</a>	
  
	
  	
  
</form>
Backbone.js
<h2><%=	
  @model.displayName()	
  %></h2>	
  
	
  	
  
<form>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  

<input	
  type='text'	
  class='input-­‐xxlarge'	
  value='<%=	
  @model.get("title")	
  
%>'id='brewery-­‐title'>	
  
	
  	
  	
  	
  	
  	
  

	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  value='<%=	
  @model.get("synonyms")	
  %>'id='brewery-­‐synonyms'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="address">Address</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <textarea	
  class='input-­‐xxlarge'	
  id='brewery-­‐address'><%=	
  @model.get("address")	
  %></textarea>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <button	
  class='btn	
  btn-­‐primary'	
  id='save-­‐button'>Save</button>	
  
	
  	
  <a	
  href="/breweries/<%=	
  @model.id	
  %>"	
  class='btn'>Cancel</a>	
  
	
  	
  
</form>
Backbone.js
<h2><%=	
  @model.displayName()	
  %></h2>	
  
	
  	
  
<form>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  value='<%=	
  @model.get("title")	
  %>'id='brewery-­‐title'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  value='<%=	
  @model.get("synonyms")	
  %>'id='brewery-­‐synonyms'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="address">Address</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  

<textarea	
  class='input-­‐xxlarge'	
  id='brewery-­‐address'><%=	
  @model.get("address")	
  
%></textarea>	
  
	
  	
  	
  	
  	
  	
  

	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <button	
  class='btn	
  btn-­‐primary'	
  id='save-­‐button'>Save</button>	
  
	
  	
  <a	
  href="/breweries/<%=	
  @model.id	
  %>"	
  class='btn'>Cancel</a>	
  
	
  	
  
</form>
Ember
<div	
  class='span12'>	
  
	
  	
  <h2>{{displayName}}</h2>	
  
	
  	
  <h3>	
  
	
  	
  	
  	
  {{cityState}}	
  
	
  	
  	
  	
  {{#linkTo	
  "country"	
  country}}	
  
	
  	
  	
  	
  	
  	
  {{country.title}}	
  
	
  	
  	
  	
  {{/linkTo}}	
  
	
  	
  </h3>	
  
	
  	
  {{#if	
  isEditing}}	
  
	
  	
  	
  	
  <form>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {{view	
  Ember.TextField	
  valueBinding="title"	
  class='input-­‐xxlarge'}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {{view	
  Ember.TextField	
  valueBinding="synonyms"	
  class='input-­‐xxlarge'}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {{view	
  Ember.TextArea	
  valueBinding="address"	
  class='input-­‐xxlarge'}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <button	
  class='btn	
  btn-­‐primary'	
  {{action	
  "save"}}>Save</button>	
  
	
  	
  
	
  	
  	
  	
  </form>	
  
	
  	
  {{	
  else	
  }}	
  
	
  	
  	
  	
  {{	
  partial	
  "brewery/show"	
  }}	
  
	
  	
  {{/if}}	
  
</div>
Ember
<div	
  class='span12'>	
  
	
  	
  <h2>{{displayName}}</h2>	
  
	
  	
  <h3>	
  
	
  	
  	
  	
  {{cityState}}	
  
	
  	
  	
  	
  {{#linkTo	
  "country"	
  country}}	
  
	
  	
  	
  	
  	
  	
  {{country.title}}	
  
	
  	
  	
  	
  {{/linkTo}}	
  
	
  	
  </h3>	
  
	
  	
  {{#if	
  isEditing}}	
  
	
  	
  	
  	
  <form>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  

{{view	
  Ember.TextField	
  valueBinding="title"	
  class='input-­‐xxlarge'}}	
  

	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  

	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {{view	
  Ember.TextField	
  valueBinding="synonyms"	
  class='input-­‐xxlarge'}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {{view	
  Ember.TextArea	
  valueBinding="address"	
  class='input-­‐xxlarge'}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <button	
  class='btn	
  btn-­‐primary'	
  {{action	
  "save"}}>Save</button>	
  
	
  	
  
	
  	
  	
  	
  </form>	
  
	
  	
  {{	
  else	
  }}	
  
	
  	
  	
  	
  {{	
  partial	
  "brewery/show"	
  }}	
  
	
  	
  {{/if}}	
  
</div>
Ember
<div	
  class='span12'>	
  
	
  	
  <h2>{{displayName}}</h2>	
  
	
  	
  <h3>	
  
	
  	
  	
  	
  {{cityState}}	
  
	
  	
  	
  	
  {{#linkTo	
  "country"	
  country}}	
  
	
  	
  	
  	
  	
  	
  {{country.title}}	
  
	
  	
  	
  	
  {{/linkTo}}	
  
	
  	
  </h3>	
  
	
  	
  {{#if	
  isEditing}}	
  
	
  	
  	
  	
  <form>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {{view	
  Ember.TextField	
  valueBinding="title"	
  class='input-­‐xxlarge'}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {{view	
  Ember.TextField	
  valueBinding="synonyms"	
  class='input-­‐xxlarge'}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  
	
  	
  	
  	
  	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {{view	
  Ember.TextArea	
  valueBinding="address"	
  class='input-­‐xxlarge'}}	
  
	
  	
  	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  	
  	
  	
  	
  </div>	
  
	
  	
  

<button	
  class='btn	
  btn-­‐primary'	
  {{action	
  "save"}}>Save</button>	
  

	
  	
  	
  	
  	
  	
  

	
  	
  
	
  	
  	
  	
  </form>	
  
	
  	
  {{	
  else	
  }}	
  
	
  	
  	
  	
  {{	
  partial	
  "brewery/show"	
  }}	
  
	
  	
  {{/if}}	
  
</div>
AngularJS
<form>	
  
	
  	
  <h3>{{brewery.title}}</h3>	
  
	
  	
  <div	
  ng-­‐include='"/assets/_errors.html"'></div>	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.title'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.synonyms'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="address">Address</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <textarea	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.address'></textarea>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <button	
  class='btn	
  btn-­‐primary'	
  ng-­‐click='save()'>Save</button>	
  
	
  	
  
</form>
AngularJS
<form>	
  
	
  	
  <h3>{{brewery.title}}</h3>	
  
	
  	
  <div	
  ng-­‐include='"/assets/_errors.html"'></div>	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.title'> 	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.synonyms'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="address">Address</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <textarea	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.address'></textarea>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <button	
  class='btn	
  btn-­‐primary'	
  ng-­‐click='save()'>Save</button>	
  
	
  	
  
</form>
AngularJS
<form>	
  
	
  	
  <h3>{{brewery.title}}</h3>	
  
	
  	
  <div	
  ng-­‐include='"/assets/_errors.html"'></div>	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="title">Title</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.title'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="synonyms">Synonyms</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <input	
  type='text'	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.synonyms'>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <div	
  class="control-­‐group">	
  
	
  	
  	
  	
  <label	
  class="control-­‐label"	
  for="address">Address</label>	
  
	
  	
  	
  	
  <div	
  class="controls">	
  
	
  	
  	
  	
  	
  	
  <textarea	
  class='input-­‐xxlarge'	
  ng-­‐model='brewery.address'></textarea>	
  
	
  	
  	
  	
  </div>	
  
	
  	
  </div>	
  
	
  	
  
	
  	
  <button	
  class='btn	
  btn-­‐primary'	
  ng-­‐click='save()'>Save</button> 	
  
	
  	
  
</form>
Round	

6
pros/cons
Backbone.js
Pros

Cons

•

Lightweight	


•

Too simple	


•

Not opinionated	


•

Not opinionated enough	


•

Simple	


•

“Memory” management	


•

Easy to read source	


•

Unstructured	


•

“widget” development

•

Spaghetti code
Ember
Pros

Cons

•

Too complex	


•

Overly opinionated	


•

Heavyweight	


•

Structured	


•

Highly opinionated	


•

ember-data - not production ready	


“less” code	


•

API always in flux	


•

Buggy	


•

Little to no mind-share outside of Rails	


•

Difficult to read source code

•
•

“large” apps
AngularJS
Pros

•

Lightly structured	


•

Lightly opinionated	


•

“less” code	


•

Plain JavaScript	


•

Simple/Powerful	


•

Easy to test	


•

Lightweight	


•

small, medium, or large apps

Cons

•

Difficult to read source code	


•

jQuery plugins require custom
directives	


•

Large apps requiring self-imposed
structure
Summary
think before you choose
don’t cargo cult
don’t use Backbone.js!
play with them all
watch the metacasts.tv	

episodes on them ;)
@markbates
http://www.metacasts.tv

More Related Content

What's hot

Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Chris Alfano
 
ActiveResource & REST
ActiveResource & RESTActiveResource & REST
ActiveResource & REST
Robbert
 
Introduction to backbone presentation
Introduction to backbone presentationIntroduction to backbone presentation
Introduction to backbone presentation
Brian Hogg
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Joao Lucas Santana
 
Modular and Event-Driven JavaScript
Modular and Event-Driven JavaScriptModular and Event-Driven JavaScript
Modular and Event-Driven JavaScript
Eduardo Shiota Yasuda
 
How routing works in angular js
How routing works in angular jsHow routing works in angular js
How routing works in angular js
codeandyou forums
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
Dzmitry Ivashutsin
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful Rails
Ben Scofield
 
Curso Symfony - Clase 3
Curso Symfony - Clase 3Curso Symfony - Clase 3
Curso Symfony - Clase 3
Javier Eguiluz
 
Keeping It Simple
Keeping It SimpleKeeping It Simple
Keeping It Simple
Stephanie Leary
 
Zazzy WordPress Navigation WordCamp Milwaukee
Zazzy WordPress Navigation WordCamp MilwaukeeZazzy WordPress Navigation WordCamp Milwaukee
Zazzy WordPress Navigation WordCamp Milwaukee
Rachel Baker
 
Bootstrap 4 ppt
Bootstrap 4 pptBootstrap 4 ppt
Bootstrap 4 ppt
EPAM Systems
 
Chef 0.8, Knife and Amazon EC2
Chef 0.8, Knife and Amazon EC2Chef 0.8, Knife and Amazon EC2
Chef 0.8, Knife and Amazon EC2
Robert Berger
 
实战Ecos
实战Ecos实战Ecos
实战Ecos
wanglei999
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant TrainingAidIQ
 
Responsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da WebResponsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da Web
Eduardo Shiota Yasuda
 
Create a mobile web app with Sencha Touch
Create a mobile web app with Sencha TouchCreate a mobile web app with Sencha Touch
Create a mobile web app with Sencha TouchJames Pearce
 
Modules and injector
Modules and injectorModules and injector
Modules and injector
Eyal Vardi
 
QCon 2015 - Thinking in components: A new paradigm for Web UI
QCon 2015 - Thinking in components: A new paradigm for Web UIQCon 2015 - Thinking in components: A new paradigm for Web UI
QCon 2015 - Thinking in components: A new paradigm for Web UI
Oliver Häger
 

What's hot (20)

Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011Jarv.us Showcase — SenchaCon 2011
Jarv.us Showcase — SenchaCon 2011
 
ActiveResource & REST
ActiveResource & RESTActiveResource & REST
ActiveResource & REST
 
Introduction to backbone presentation
Introduction to backbone presentationIntroduction to backbone presentation
Introduction to backbone presentation
 
Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)Desenvolvimento web com Ruby on Rails (parte 2)
Desenvolvimento web com Ruby on Rails (parte 2)
 
Modular and Event-Driven JavaScript
Modular and Event-Driven JavaScriptModular and Event-Driven JavaScript
Modular and Event-Driven JavaScript
 
How routing works in angular js
How routing works in angular jsHow routing works in angular js
How routing works in angular js
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 
Advanced RESTful Rails
Advanced RESTful RailsAdvanced RESTful Rails
Advanced RESTful Rails
 
Curso Symfony - Clase 3
Curso Symfony - Clase 3Curso Symfony - Clase 3
Curso Symfony - Clase 3
 
Keeping It Simple
Keeping It SimpleKeeping It Simple
Keeping It Simple
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
Zazzy WordPress Navigation WordCamp Milwaukee
Zazzy WordPress Navigation WordCamp MilwaukeeZazzy WordPress Navigation WordCamp Milwaukee
Zazzy WordPress Navigation WordCamp Milwaukee
 
Bootstrap 4 ppt
Bootstrap 4 pptBootstrap 4 ppt
Bootstrap 4 ppt
 
Chef 0.8, Knife and Amazon EC2
Chef 0.8, Knife and Amazon EC2Chef 0.8, Knife and Amazon EC2
Chef 0.8, Knife and Amazon EC2
 
实战Ecos
实战Ecos实战Ecos
实战Ecos
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
 
Responsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da WebResponsive Web Design e a Ubiquidade da Web
Responsive Web Design e a Ubiquidade da Web
 
Create a mobile web app with Sencha Touch
Create a mobile web app with Sencha TouchCreate a mobile web app with Sencha Touch
Create a mobile web app with Sencha Touch
 
Modules and injector
Modules and injectorModules and injector
Modules and injector
 
QCon 2015 - Thinking in components: A new paradigm for Web UI
QCon 2015 - Thinking in components: A new paradigm for Web UIQCon 2015 - Thinking in components: A new paradigm for Web UI
QCon 2015 - Thinking in components: A new paradigm for Web UI
 

Viewers also liked

Introduction to Backbone.js
Introduction to Backbone.jsIntroduction to Backbone.js
Introduction to Backbone.js
Jonathan Weiss
 
Introduction to Backbone.js
Introduction to Backbone.jsIntroduction to Backbone.js
Introduction to Backbone.js
Roman Kalyakin
 
Introduction à Marionette
Introduction à MarionetteIntroduction à Marionette
Introduction à Marionette
Raphaël Lemaire
 
Backbone And Marionette : Take Over The World
Backbone And Marionette : Take Over The WorldBackbone And Marionette : Take Over The World
Backbone And Marionette : Take Over The World
harshit040591
 
Intro to Backbone.js by Azat Mardanov for General Assembly
Intro to Backbone.js by Azat Mardanov for General AssemblyIntro to Backbone.js by Azat Mardanov for General Assembly
Intro to Backbone.js by Azat Mardanov for General Assembly
Azat Mardanov
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
Knoldus Inc.
 
Beautiful Maintainable ModularJavascript Codebase with RequireJS - HelsinkiJ...
 Beautiful Maintainable ModularJavascript Codebase with RequireJS - HelsinkiJ... Beautiful Maintainable ModularJavascript Codebase with RequireJS - HelsinkiJ...
Beautiful Maintainable ModularJavascript Codebase with RequireJS - HelsinkiJ...
Mikko Ohtamaa
 
Backbone/Marionette recap [2015]
Backbone/Marionette recap [2015]Backbone/Marionette recap [2015]
Backbone/Marionette recap [2015]
Andrii Lundiak
 
Introduction to Marionette Collective
Introduction to Marionette CollectiveIntroduction to Marionette Collective
Introduction to Marionette Collective
Puppet
 
Backbone/Marionette introduction
Backbone/Marionette introductionBackbone/Marionette introduction
Backbone/Marionette introduction
matt-briggs
 
Introduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.jsIntroduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.js
Return on Intelligence
 
Marionette talk 2016
Marionette talk 2016Marionette talk 2016
Marionette talk 2016
Kseniya Redunova
 
Client-side MVC with Backbone.js
Client-side MVC with Backbone.js Client-side MVC with Backbone.js
Client-side MVC with Backbone.js
iloveigloo
 
introduction to Marionette.js (jscafe14)
introduction to Marionette.js (jscafe14)introduction to Marionette.js (jscafe14)
introduction to Marionette.js (jscafe14)
Ryuma Tsukano
 
Marionette: the Backbone framework
Marionette: the Backbone frameworkMarionette: the Backbone framework
Marionette: the Backbone framework
frontendne
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
VO Tho
 
RequireJS
RequireJSRequireJS
Introduction to Backbone.js
Introduction to Backbone.jsIntroduction to Backbone.js
Introduction to Backbone.jsPragnesh Vaghela
 
RequireJS
RequireJSRequireJS
RequireJS
Tim Doherty
 

Viewers also liked (20)

Introduction to Backbone.js
Introduction to Backbone.jsIntroduction to Backbone.js
Introduction to Backbone.js
 
Introduction to Backbone.js
Introduction to Backbone.jsIntroduction to Backbone.js
Introduction to Backbone.js
 
Introduction à Marionette
Introduction à MarionetteIntroduction à Marionette
Introduction à Marionette
 
Backbone And Marionette : Take Over The World
Backbone And Marionette : Take Over The WorldBackbone And Marionette : Take Over The World
Backbone And Marionette : Take Over The World
 
Intro to Backbone.js by Azat Mardanov for General Assembly
Intro to Backbone.js by Azat Mardanov for General AssemblyIntro to Backbone.js by Azat Mardanov for General Assembly
Intro to Backbone.js by Azat Mardanov for General Assembly
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
MVC & backbone.js
MVC & backbone.jsMVC & backbone.js
MVC & backbone.js
 
Beautiful Maintainable ModularJavascript Codebase with RequireJS - HelsinkiJ...
 Beautiful Maintainable ModularJavascript Codebase with RequireJS - HelsinkiJ... Beautiful Maintainable ModularJavascript Codebase with RequireJS - HelsinkiJ...
Beautiful Maintainable ModularJavascript Codebase with RequireJS - HelsinkiJ...
 
Backbone/Marionette recap [2015]
Backbone/Marionette recap [2015]Backbone/Marionette recap [2015]
Backbone/Marionette recap [2015]
 
Introduction to Marionette Collective
Introduction to Marionette CollectiveIntroduction to Marionette Collective
Introduction to Marionette Collective
 
Backbone/Marionette introduction
Backbone/Marionette introductionBackbone/Marionette introduction
Backbone/Marionette introduction
 
Introduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.jsIntroduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.js
 
Marionette talk 2016
Marionette talk 2016Marionette talk 2016
Marionette talk 2016
 
Client-side MVC with Backbone.js
Client-side MVC with Backbone.js Client-side MVC with Backbone.js
Client-side MVC with Backbone.js
 
introduction to Marionette.js (jscafe14)
introduction to Marionette.js (jscafe14)introduction to Marionette.js (jscafe14)
introduction to Marionette.js (jscafe14)
 
Marionette: the Backbone framework
Marionette: the Backbone frameworkMarionette: the Backbone framework
Marionette: the Backbone framework
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
RequireJS
RequireJSRequireJS
RequireJS
 
Introduction to Backbone.js
Introduction to Backbone.jsIntroduction to Backbone.js
Introduction to Backbone.js
 
RequireJS
RequireJSRequireJS
RequireJS
 

Similar to AngularJS vs. Ember.js vs. Backbone.js

Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js Fundamentals
Mark
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
TechExeter
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overviewYehuda Katz
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the FinishYehuda Katz
 
Working with Javascript in Rails
Working with Javascript in RailsWorking with Javascript in Rails
Working with Javascript in Rails
Seungkyun Nam
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
Daniel Cukier
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesNCCOMMS
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
Marcus Ramberg
 
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
Masakuni Kato
 
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface
 
Rails MVC by Sergiy Koshovyi
Rails MVC by Sergiy KoshovyiRails MVC by Sergiy Koshovyi
Rails MVC by Sergiy Koshovyi
Pivorak MeetUp
 
Java Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom TagsJava Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom Tags
IMC Institute
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
Rafael Felix da Silva
 
QConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebQConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações Web
Fabio Akita
 
Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02
Revath S Kumar
 
Single Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and RailsSingle Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and Rails
Prateek Dayal
 
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component DevelopmentEVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
Evolve The Adobe Digital Marketing Community
 
Optimizing Angular Performance in Enterprise Single Page Apps
Optimizing Angular Performance in Enterprise Single Page AppsOptimizing Angular Performance in Enterprise Single Page Apps
Optimizing Angular Performance in Enterprise Single Page Apps
Morgan Stone
 
Survey of Front End Topics in Rails
Survey of Front End Topics in RailsSurvey of Front End Topics in Rails
Survey of Front End Topics in RailsBenjamin Vandgrift
 

Similar to AngularJS vs. Ember.js vs. Backbone.js (20)

Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js Fundamentals
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
 
Rails 3 overview
Rails 3 overviewRails 3 overview
Rails 3 overview
 
Rails 3: Dashing to the Finish
Rails 3: Dashing to the FinishRails 3: Dashing to the Finish
Rails 3: Dashing to the Finish
 
Working with Javascript in Rails
Working with Javascript in RailsWorking with Javascript in Rails
Working with Javascript in Rails
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Spca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_librariesSpca2014 hillier 3rd party_javascript_libraries
Spca2014 hillier 3rd party_javascript_libraries
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
浜松Rails3道場 其の壱 プロジェクト作成〜Rouging編
 
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
 
Rails MVC by Sergiy Koshovyi
Rails MVC by Sergiy KoshovyiRails MVC by Sergiy Koshovyi
Rails MVC by Sergiy Koshovyi
 
Java Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom TagsJava Web Programming [5/9] : EL, JSTL and Custom Tags
Java Web Programming [5/9] : EL, JSTL and Custom Tags
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 
QConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações WebQConSP 2015 - Dicas de Performance para Aplicações Web
QConSP 2015 - Dicas de Performance para Aplicações Web
 
Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02Prateek dayal backbonerails-110528024926-phpapp02
Prateek dayal backbonerails-110528024926-phpapp02
 
Single Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and RailsSingle Page Web Apps with Backbone.js and Rails
Single Page Web Apps with Backbone.js and Rails
 
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component DevelopmentEVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
 
Optimizing Angular Performance in Enterprise Single Page Apps
Optimizing Angular Performance in Enterprise Single Page AppsOptimizing Angular Performance in Enterprise Single Page Apps
Optimizing Angular Performance in Enterprise Single Page Apps
 
Survey of Front End Topics in Rails
Survey of Front End Topics in RailsSurvey of Front End Topics in Rails
Survey of Front End Topics in Rails
 

More from Mark

Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web Apps
Mark
 
Go(lang) for the Rubyist
Go(lang) for the RubyistGo(lang) for the Rubyist
Go(lang) for the Rubyist
Mark
 
Mangling Ruby with TracePoint
Mangling Ruby with TracePointMangling Ruby with TracePoint
Mangling Ruby with TracePoint
Mark
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTest
Mark
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTest
Mark
 
GET /better
GET /betterGET /better
GET /better
Mark
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
Mark
 
Testing Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScriptTesting Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScript
Mark
 
Building an API in Rails without Realizing It
Building an API in Rails without Realizing ItBuilding an API in Rails without Realizing It
Building an API in Rails without Realizing It
Mark
 
5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(
Mark
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the Rubyist
Mark
 
RubyMotion
RubyMotionRubyMotion
RubyMotion
Mark
 
Testing JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and ChaiTesting JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and Chai
Mark
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the Rubyist
Mark
 
Testing Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with JasmineTesting Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with Jasmine
Mark
 
DRb and Rinda
DRb and RindaDRb and Rinda
DRb and Rinda
Mark
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
Mark
 
Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010
Mark
 

More from Mark (18)

Building Go Web Apps
Building Go Web AppsBuilding Go Web Apps
Building Go Web Apps
 
Go(lang) for the Rubyist
Go(lang) for the RubyistGo(lang) for the Rubyist
Go(lang) for the Rubyist
 
Mangling Ruby with TracePoint
Mangling Ruby with TracePointMangling Ruby with TracePoint
Mangling Ruby with TracePoint
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTest
 
A Big Look at MiniTest
A Big Look at MiniTestA Big Look at MiniTest
A Big Look at MiniTest
 
GET /better
GET /betterGET /better
GET /better
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Testing Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScriptTesting Your JavaScript & CoffeeScript
Testing Your JavaScript & CoffeeScript
 
Building an API in Rails without Realizing It
Building an API in Rails without Realizing ItBuilding an API in Rails without Realizing It
Building an API in Rails without Realizing It
 
5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(5 Favorite Gems (Lightning Talk(
5 Favorite Gems (Lightning Talk(
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the Rubyist
 
RubyMotion
RubyMotionRubyMotion
RubyMotion
 
Testing JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and ChaiTesting JavaScript/CoffeeScript with Mocha and Chai
Testing JavaScript/CoffeeScript with Mocha and Chai
 
CoffeeScript for the Rubyist
CoffeeScript for the RubyistCoffeeScript for the Rubyist
CoffeeScript for the Rubyist
 
Testing Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with JasmineTesting Rich Client Side Apps with Jasmine
Testing Rich Client Side Apps with Jasmine
 
DRb and Rinda
DRb and RindaDRb and Rinda
DRb and Rinda
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
 
Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010Distributed Programming with Ruby/Rubyconf 2010
Distributed Programming with Ruby/Rubyconf 2010
 

Recently uploaded

Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
OnBoard
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 

Recently uploaded (20)

Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Leading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdfLeading Change strategies and insights for effective change management pdf 1.pdf
Leading Change strategies and insights for effective change management pdf 1.pdf
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 

AngularJS vs. Ember.js vs. Backbone.js

  • 3.
  • 4.
  • 5.
  • 7. AngularJS vs. Ember vs. Backbone.js
  • 10. Backbone.js “minimal set of data-structure and view primitives for building web application with JavaScript”
  • 11. Backbone.js do what you want, however you want to do it (we won’t tell anyone)
  • 12. Ember “framework for creating ambitious web applications”
  • 14. AngularJS “Toolset for building the framework most suited to your application development”
  • 16.
  • 17.
  • 18.
  • 25. Backbone.js class  App.Beer  extends  Backbone.Model       class  App.Beers  extends  Backbone.Collection   !  model:  Beer
  • 26. Ember App.Beer  =  DS.Model.extend      title:  DS.attr("string")      abv:  DS.attr("number")      country_id:  DS.attr("number")      brewery_id:  DS.attr("number")      brewery:  DS.belongsTo("App.Brewery")      country:  DS.belongsTo("App.Country")
  • 29. Backbone.js class  App.Beer  extends  Backbone.Model      urlRoot:  "/api/v1/beers"         class  App.Beers  extends  Backbone.Collection          url:  -­‐>          if  @brewery_id?              return  "/api/v1/breweries/#{@brewery_id}/beers"          else              return  "/api/v1/beers"          model:  Beer
  • 30. Ember App.Beer  =  DS.Model.extend      title:  DS.attr("string")      abv:  DS.attr("number")      country_id:  DS.attr("number")      brewery_id:  DS.attr("number")      brewery:  DS.belongsTo("App.Brewery")      country:  DS.belongsTo("App.Country")
  • 31. Ember DS.RESTAdapter.reopen      namespace:  'api/v1'       App.Store  =  DS.Store.extend      revision:  11      adapter:  DS.RESTAdapter.create()
  • 32. AngularJS App.factory  "Beer",  ($resource)  -­‐>      return  $resource  "/api/v1/beers/:id",                                        {id:  "@id"},                                        {update:  {method:  "PUT"}}
  • 35. Backbone.js @Router  =  Backbone.Router.extend          initialize:  -­‐>          @countries  =  new  Countries()          routes:          "breweries/:brewery_id":  "brewery"          "breweries/:brewery_id/edit":  "breweryEdit"          brewery:  (brewery_id)  -­‐>          @changeView(new  BreweryView(collection:  @countries,  model:  new  Brewery(id:  brewery_id)))          breweryEdit:  (brewery_id)  -­‐>          @changeView(new  BreweryEditView(collection:  @countries,  model:  new  Brewery(id:  brewery_id)))          changeView:  (view)  =>          @currentView?.remove()          @currentView  =  view          $("#outlet").html(@currentView.el)
  • 36. Ember App.Router.map  -­‐>      @resource  "brewery",  {path:  "brewery/:brewery_id"}
  • 37. Ember App.BreweryRoute  =  Ember.Route.extend      model:  (params)-­‐>          App.Brewery.find(params.brewery_id)
  • 38. AngularJS App.config  ($routeProvider)  -­‐>          $routeProvider          .when("/breweries/:id",  {              templateUrl:  "/assets/brewery.html",              controller:  "BreweryController"          })          .when("/breweries/:id/edit",  {              templateUrl:  "/assets/edit_brewery.html",              controller:  "EditBreweryController"          })
  • 41. Backbone.js class  @BreweryEditView  extends  Backbone.View          template:  "brewery_edit"          events:          "click  #save-­‐button":  "saveClicked"          "keypress  #brewery-­‐title":  "titleEdited"          initialize:  -­‐>          super          @countriesView  =  new  CountriesView(collection:  @collection)          @$el.html(@countriesView.el)          @model.on  "change",  @render          @model.fetch()          render:  =>          @$("#country-­‐outlet").html(@renderTemplate())          return  @    saveClicked:  (e)  =>          e?.preventDefault()          attrs  =              title:  @$("#brewery-­‐title").val()              synonyms:  @$("#brewery-­‐synonyms").val()              address:  @$("#brewery-­‐address").val()          @model.save  attrs,              success:  (model,  response,  options)  =>                  App.navigate("/breweries/#{@model.id}",  trigger:  true)              error:  (model,  xhr,  options)  -­‐>                  errors  =  []                  for  key,  value  of  xhr.responseJSON.errors                      errors.push  "#{key}:  #{value.join(",  ")}"                  alert  errors.join("n")          titleEdited:  (e)  =>          title  =  @$("#brewery-­‐title").val()          @$("h2").text(title)   !    #  further  code  omitted
  • 42. Ember App.BreweryController  =  Ember.ObjectController.extend        save:  -­‐>          @store.commit()          #  further  code  omitted
  • 43. AngularJS @EditBreweryController  =  ($scope,  $routeParams,  $location,  Brewery)  -­‐>          $scope.brewery  =  Brewery.get(id:  $routeParams.id)          $scope.save  =  -­‐>          success  =  -­‐>              $location.path("/breweries/#{$routeParams.id}")              $scope.errors  =  null          failure  =  (object)-­‐>              $scope.errors  =  object.data.errors          $scope.brewery.$update  {},  success,  failure
  • 46. Backbone.js <h2><%=  @model.displayName()  %></h2>       <form>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="title">Title</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  value='<%=  @model.get("title")  %>'id='brewery-­‐title'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="synonyms">Synonyms</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  value='<%=  @model.get("synonyms")  %>'id='brewery-­‐synonyms'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="address">Address</label>          <div  class="controls">              <textarea  class='input-­‐xxlarge'  id='brewery-­‐address'><%=  @model.get("address")  %></textarea>          </div>      </div>          <button  class='btn  btn-­‐primary'  id='save-­‐button'>Save</button>      <a  href="/breweries/<%=  @model.id  %>"  class='btn'>Cancel</a>       </form>
  • 47. Backbone.js <h2><%=  @model.displayName()  %></h2>       <form>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="title">Title</label>          <div  class="controls">   <input  type='text'  class='input-­‐xxlarge'  value='<%=  @model.get("title")   %>'id='brewery-­‐title'>                      </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="synonyms">Synonyms</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  value='<%=  @model.get("synonyms")  %>'id='brewery-­‐synonyms'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="address">Address</label>          <div  class="controls">              <textarea  class='input-­‐xxlarge'  id='brewery-­‐address'><%=  @model.get("address")  %></textarea>          </div>      </div>          <button  class='btn  btn-­‐primary'  id='save-­‐button'>Save</button>      <a  href="/breweries/<%=  @model.id  %>"  class='btn'>Cancel</a>       </form>
  • 48. Backbone.js <h2><%=  @model.displayName()  %></h2>       <form>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="title">Title</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  value='<%=  @model.get("title")  %>'id='brewery-­‐title'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="synonyms">Synonyms</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  value='<%=  @model.get("synonyms")  %>'id='brewery-­‐synonyms'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="address">Address</label>          <div  class="controls">   <textarea  class='input-­‐xxlarge'  id='brewery-­‐address'><%=  @model.get("address")   %></textarea>                      </div>      </div>          <button  class='btn  btn-­‐primary'  id='save-­‐button'>Save</button>      <a  href="/breweries/<%=  @model.id  %>"  class='btn'>Cancel</a>       </form>
  • 49. Ember <div  class='span12'>      <h2>{{displayName}}</h2>      <h3>          {{cityState}}          {{#linkTo  "country"  country}}              {{country.title}}          {{/linkTo}}      </h3>      {{#if  isEditing}}          <form>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="title">Title</label>                  <div  class="controls">                      {{view  Ember.TextField  valueBinding="title"  class='input-­‐xxlarge'}}                  </div>              </div>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="synonyms">Synonyms</label>                  <div  class="controls">                      {{view  Ember.TextField  valueBinding="synonyms"  class='input-­‐xxlarge'}}                  </div>              </div>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="synonyms">Synonyms</label>                  <div  class="controls">                      {{view  Ember.TextArea  valueBinding="address"  class='input-­‐xxlarge'}}                  </div>              </div>                  <button  class='btn  btn-­‐primary'  {{action  "save"}}>Save</button>              </form>      {{  else  }}          {{  partial  "brewery/show"  }}      {{/if}}   </div>
  • 50. Ember <div  class='span12'>      <h2>{{displayName}}</h2>      <h3>          {{cityState}}          {{#linkTo  "country"  country}}              {{country.title}}          {{/linkTo}}      </h3>      {{#if  isEditing}}          <form>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="title">Title</label>                  <div  class="controls">   {{view  Ember.TextField  valueBinding="title"  class='input-­‐xxlarge'}}                                      </div>              </div>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="synonyms">Synonyms</label>                  <div  class="controls">                      {{view  Ember.TextField  valueBinding="synonyms"  class='input-­‐xxlarge'}}                  </div>              </div>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="synonyms">Synonyms</label>                  <div  class="controls">                      {{view  Ember.TextArea  valueBinding="address"  class='input-­‐xxlarge'}}                  </div>              </div>                  <button  class='btn  btn-­‐primary'  {{action  "save"}}>Save</button>              </form>      {{  else  }}          {{  partial  "brewery/show"  }}      {{/if}}   </div>
  • 51. Ember <div  class='span12'>      <h2>{{displayName}}</h2>      <h3>          {{cityState}}          {{#linkTo  "country"  country}}              {{country.title}}          {{/linkTo}}      </h3>      {{#if  isEditing}}          <form>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="title">Title</label>                  <div  class="controls">                      {{view  Ember.TextField  valueBinding="title"  class='input-­‐xxlarge'}}                  </div>              </div>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="synonyms">Synonyms</label>                  <div  class="controls">                      {{view  Ember.TextField  valueBinding="synonyms"  class='input-­‐xxlarge'}}                  </div>              </div>                  <div  class="control-­‐group">                  <label  class="control-­‐label"  for="synonyms">Synonyms</label>                  <div  class="controls">                      {{view  Ember.TextArea  valueBinding="address"  class='input-­‐xxlarge'}}                  </div>              </div>       <button  class='btn  btn-­‐primary'  {{action  "save"}}>Save</button>                          </form>      {{  else  }}          {{  partial  "brewery/show"  }}      {{/if}}   </div>
  • 52. AngularJS <form>      <h3>{{brewery.title}}</h3>      <div  ng-­‐include='"/assets/_errors.html"'></div>      <div  class="control-­‐group">          <label  class="control-­‐label"  for="title">Title</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  ng-­‐model='brewery.title'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="synonyms">Synonyms</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  ng-­‐model='brewery.synonyms'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="address">Address</label>          <div  class="controls">              <textarea  class='input-­‐xxlarge'  ng-­‐model='brewery.address'></textarea>          </div>      </div>          <button  class='btn  btn-­‐primary'  ng-­‐click='save()'>Save</button>       </form>
  • 53. AngularJS <form>      <h3>{{brewery.title}}</h3>      <div  ng-­‐include='"/assets/_errors.html"'></div>      <div  class="control-­‐group">          <label  class="control-­‐label"  for="title">Title</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  ng-­‐model='brewery.title'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="synonyms">Synonyms</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  ng-­‐model='brewery.synonyms'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="address">Address</label>          <div  class="controls">              <textarea  class='input-­‐xxlarge'  ng-­‐model='brewery.address'></textarea>          </div>      </div>          <button  class='btn  btn-­‐primary'  ng-­‐click='save()'>Save</button>       </form>
  • 54. AngularJS <form>      <h3>{{brewery.title}}</h3>      <div  ng-­‐include='"/assets/_errors.html"'></div>      <div  class="control-­‐group">          <label  class="control-­‐label"  for="title">Title</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  ng-­‐model='brewery.title'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="synonyms">Synonyms</label>          <div  class="controls">              <input  type='text'  class='input-­‐xxlarge'  ng-­‐model='brewery.synonyms'>          </div>      </div>          <div  class="control-­‐group">          <label  class="control-­‐label"  for="address">Address</label>          <div  class="controls">              <textarea  class='input-­‐xxlarge'  ng-­‐model='brewery.address'></textarea>          </div>      </div>          <button  class='btn  btn-­‐primary'  ng-­‐click='save()'>Save</button>       </form>
  • 57. Backbone.js Pros Cons • Lightweight • Too simple • Not opinionated • Not opinionated enough • Simple • “Memory” management • Easy to read source • Unstructured • “widget” development • Spaghetti code
  • 58. Ember Pros Cons • Too complex • Overly opinionated • Heavyweight • Structured • Highly opinionated • ember-data - not production ready “less” code • API always in flux • Buggy • Little to no mind-share outside of Rails • Difficult to read source code • • “large” apps
  • 59. AngularJS Pros • Lightly structured • Lightly opinionated • “less” code • Plain JavaScript • Simple/Powerful • Easy to test • Lightweight • small, medium, or large apps Cons • Difficult to read source code • jQuery plugins require custom directives • Large apps requiring self-imposed structure