Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
AngularJS vs. Ember.js vs. Backbone.js
Search
Kod.io
October 26, 2013
Programming
530
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
AngularJS vs. Ember.js vs. Backbone.js
By Mark Bates
http://kod.io
Kod.io
October 26, 2013
More Decks by Kod.io
See All by Kod.io
Our future is in our past or whatever
kodio
0
73
You should learn Go!
kodio
1
140
Daha iyi Geliştirme Ortamı için: Vagrant
kodio
0
83
Building Next-Generation iOS Apps with AFNetworking 2.0
kodio
2
400
Reactive Principles
kodio
1
160
iBeacons: Interacting with the physical world using Bluetooth LE
kodio
1
110
Go: a simple programming environment
kodio
2
180
Why I had to write a client side framework for Koding.
kodio
1
110
Sure, I could learn Objective-C but...
kodio
1
100
Other Decks in Programming
See All in Programming
カツオ、ご期待ください
suneo3476
0
120
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
300
iOSDCのペンライトを自動制御したい!
akkeylab
0
210
Agents on Rails - Rails at Scale 2026
irinanazarova
0
290
速習iPhone Duo対応
yuukiw00w
2
910
海上で動くGoサーバー: goroutineとchannelでさばく航行データストリーム
atsuki_seo
0
1k
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
270
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
3.1k
Intent as Code
shoppingjaws
6
1.1k
iOSDC2026登壇資料.pdf
riofujimon
0
200
Verilogで学ぶCPU自作入門.pdf
uyuki234
7
3.8k
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.3k
Featured
See All Featured
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
510
Embracing the Ebb and Flow
colly
88
5.2k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
How to make the Groovebox
asonas
2
2.5k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.3k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
550
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
710
Un-Boring Meetings
codingconduct
0
430
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
250
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
Transcript
@markbates
hire me* (for rent, not sale)
None
None
None
KODIO13 www.metacasts.tv
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
None
None
None
Round 1
weight
“production” versions (minified) w/ required dependencies
AngularJS Ember Backbone.js base 81kb 235kb 6.4kb templating language built-in
73kb (handlebars) ?? data adapter built-in 210kb (ember-data) 32kb (jQuery) support 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> <input type='text' class='input-‐xxlarge' value='<%= @model.get("title") %>'id='brewery-‐title'>
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> <textarea class='input-‐xxlarge' id='brewery-‐address'><%= @model.get("address") %></textarea>
<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 {{view Ember.TextField valueBinding="title" class='input-‐xxlarge'}}
<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 <button class='btn btn-‐primary' {{action "save"}}>Save</button>
<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
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> <input type='text' class='input-‐xxlarge' ng-‐model='brewery.title'>
<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 <button class='btn btn-‐primary' ng-‐click='save()'>Save</button>
Round 6
pros/cons
Backbone.js • Too simple • Not opinionated enough • “Memory”
management • Unstructured • Spaghetti code • Lightweight • Not opinionated • Simple • Easy to read source • “widget” development Pros Cons
Ember • Too complex • Overly opinionated • Heavyweight •
ember-data - not production ready • API always in flux • Buggy • Little to no mind-share outside of Rails • Difficult to read source code • Structured • Highly opinionated • “less” code • “large” apps Pros Cons
AngularJS • Difficult to read source code • jQuery plugins
require custom directives • Large apps requiring self-imposed structure • Lightly structured • Lightly opinionated • “less” code • Plain JavaScript • Simple/Powerful • Easy to test • Lightweight • small, medium, or large apps Pros Cons
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