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
76
You should learn Go!
kodio
1
140
Daha iyi Geliştirme Ortamı için: Vagrant
kodio
0
86
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
190
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
Kotlinize Is Not Just Converting to Kotlin
chigichan24
1
210
SFCで実現する病院・医療システムの動的組み立て式UI
koukimiura
1
160
AIが生成したコードは読むべきか?抽象化設計とコードの品質保証 / abstraction-design-and-quality
minodriven
14
8.1k
Inertia Rails: The One-Person Framework with React & Friends
skryukov
0
210
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
540
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
3
2.4k
Railsバージョンを4倍にした話
optim
0
900
個人開発者よ、Honoを使え(おじさんver)
tanahiro2010
2
300
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
400
クラウドエージェントは、 何がそんなに便利なのか / what makes cloud agents so useful
rkaga
5
670
Performance Optimization With LLMs
xleitix
0
230
Python Lambdaにおけるテストしやすい設計とAI支援の活用 / Designing Testable Python Lambda Functions with AI
kitano_yuichi
1
270
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
600
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.8k
Product Roadmaps are Hard
iamctodd
55
13k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
47k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
How Software Deployment tools have changed in the past 20 years
geshan
2
35k
Exploring anti-patterns in Rails
aemeredith
4
560
Into the Great Unknown - MozCon
thekraken
41
2.8k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.2k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
310
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