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
Client Side Applications with Ember.js
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Christopher Meiklejohn
January 20, 2013
Programming
770
15
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Client Side Applications with Ember.js
Hack Harvard 2013
Christopher Meiklejohn
January 20, 2013
More Decks by Christopher Meiklejohn
See All by Christopher Meiklejohn
Towards a Solution to the Red Wedding Problem
cmeiklejohn
0
460
Language Support for Cloud-Scale Distributed Systems
cmeiklejohn
0
600
Towards a Systems Approach to Distributed Programming
cmeiklejohn
3
410
Scaling a Startup with a 21st Century Programming Language
cmeiklejohn
0
450
Practical Evaluation of the Lasp Programming Model at Scale
cmeiklejohn
4
2.9k
Just-Right Consistency - Closing the CAP Gap
cmeiklejohn
3
330
Declarative, Convergent, Edge Computation
cmeiklejohn
1
260
Just-Right Consistency - Closing the CAP Gap
cmeiklejohn
3
1.4k
A Certain Tendency of the Database Community
cmeiklejohn
0
510
Other Decks in Programming
See All in Programming
Railsのためのパスキー実践入門 〜マルチテナントSaaSでの意思決定〜
utakaha
2
640
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
750
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
0
500
AIに “答え“を書かせるのを やめてみた
___akari11
0
120
JIS keyboard support in Omarchy
lef237
0
120
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
150
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
28
32k
IBM Bob でAI駆動開発『QC-Playbook』
ichirokano2
0
110
AmebaブログはKMPから卒業します
kmars0605
0
200
Workers Cache を知る
syumai
0
370
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
280
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
190
Featured
See All Featured
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
4
4.4k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
Believing is Seeing
oripsolob
1
240
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
310
AI Search: Where Are We & What Can We Do About It?
aleyda
0
8.1k
Ecommerce SEO: The Keys for Success Now & Beyond - #SERPConf2024
aleyda
1
2.2k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
570
Navigating Team Friction
lara
192
16k
Accessibility Awareness
sabderemane
1
250
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
580
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Transcript
Client Side Applications With Ember.js Christopher Meiklejohn @cmeik Sunday, January
20, 13
Ember.js: The Dickensian Aspect Christopher Meiklejohn @cmeik Sunday, January 20,
13
@cmeik
[email protected]
Sunday, January 20, 13
Client Side Applications Runs in browser; authored in JavaScript; data
API. Sunday, January 20, 13
Client Side Applications GMail, Google+, Basho’s GiddyUp, Rdio Sunday, January
20, 13
What is Ember.js? Sunday, January 20, 13
MVC Structure Sunday, January 20, 13
Data Bindings Sunday, January 20, 13
Computed Properties Sunday, January 20, 13
Data Bound Declarative Templates Sunday, January 20, 13
State Managers Sunday, January 20, 13
Declarative Router Sunday, January 20, 13
Run Loop Sunday, January 20, 13
Ember Data Sunday, January 20, 13
Let’s get started! Sunday, January 20, 13
Object Model Sunday, January 20, 13
Objects and Classes Sunday, January 20, 13
App.Person = Ember.Object.extend({ say: function(thing) { alert(thing); } }); var
person = App.Person.create(); person.say("Hello Joe."); Sunday, January 20, 13
Observers Sunday, January 20, 13
App.Person = Ember.Object.extend({ fullNameChanged: function() { console.log('fullNameChanged!'); }.observes('fullName') }); Sunday,
January 20, 13
App.Person = Ember.Object.extend({ childMarried: function() { console.log('ERMAHGERD!'); }.observes('
[email protected]
') }); Sunday,
January 20, 13
Mixins Sunday, January 20, 13
App.Editable = Ember.Mixin.create({ edit: function() { this.set('isEditing', true); }, isEditing:
false }); App.CommentView = Ember.View.extend( App.Editable, { template: Ember.Handlebars.compile('...') }); Sunday, January 20, 13
Computed Properties Sunday, January 20, 13
App.president = Ember.Object.create({ firstName: "Barack", lastName: "Obama", fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName', 'lastName') }); App.president.get('fullName'); Sunday, January 20, 13
Controllers Sunday, January 20, 13
Controllers ObjectController ArrayController Controller Sunday, January 20, 13
Ember.ArrayController.create({ content: [object1, object2] }); Ember.ObjectController.create({ content: object3 }); Sunday,
January 20, 13
Controllers ObjectController ArrayController Controller Sunday, January 20, 13
Controllers ObjectProxy ArrayProxy Sunday, January 20, 13
App.president = Ember.Object.create({ firstName: "Barack", lastName: "Obama", fullName: function() {
return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName', 'lastName') }); App.president.get('fullName'); Sunday, January 20, 13
App.presidentController = Ember.ObjectController.create({ contentBinding: 'App.president' }); App.presidentController.get('fullName'); Sunday, January 20,
13
Views Sunday, January 20, 13
App.PresidentView = Ember.View.create({ templateName: 'president', contentBinding: 'App.president' }); <script type='text/x-handlebars'
data-template-name='president'> {{fullName}} </script> Sunday, January 20, 13
Run Loop Deferred rendering; change propagation; coalescing. Sunday, January 20,
13
App.president = Ember.Object.create({ firstName: "George W.", lastName: "Bush", fullName: function()
{ return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName', 'lastName') }); App.president.set('firstName', 'Barack'); App.president.set('lastName', 'Obama'); Sunday, January 20, 13
The Router and Application Structure Sunday, January 20, 13
Application as a series of states Sunday, January 20, 13
Application as a series of states hierarchy of views Sunday,
January 20, 13
Sunday, January 20, 13
Sunday, January 20, 13
Sunday, January 20, 13
Sunday, January 20, 13
Nested Outlets Outlet as Controller/View Pair Sunday, January 20, 13
<div class="navbar" style="margin-bottom:0"> <div class="navbar-inner"> <a class="brand" href="#">GiddyUp</a> {{outlet projects}}
</div> </div> {{outlet scorecards}} {{outlet testResults}} {{outlet scorecard}} Sunday, January 20, 13
<div class="navbar" style="margin-bottom:0"> <div class="navbar-inner"> <a class="brand" href="#">GiddyUp</a> {{outlet projects}}
</div> </div> {{outlet scorecards}} {{outlet}} Sunday, January 20, 13
Router Application as a series of states and transitions. Sunday,
January 20, 13
1. Initialize route, controller and view 2. Load model 3.
Initialize with controllers 3. Render template Sunday, January 20, 13
1. call create(); 2. call model(); 3. call setupControllers(); 3.
call renderTemplate(); Sunday, January 20, 13
GiddyUp.Router.map(function() { this.resource('projects', function() { this.route('show', { path: '/:project_id'); });
}); /** IndexRoute ProjectsRoute (Projects)IndexRoute (Projects)ShowRoute **/ Sunday, January 20, 13
GiddyUp.IndexRoute = Ember.Route.extend({ redirect: function() { this.transitionTo('projects'); } }); Sunday,
January 20, 13
GiddyUp.ProjectsRoute = Ember.Route.extend({ model: function() { return GiddyUp.Project.find(); }, setupController:
function(c, projects) { c.set('content', projects); }, renderTemplate: function() { this.render('projects', { outlet: 'projects' }); } }); Sunday, January 20, 13
GiddyUp.ProjectsShowRoute = Em.Route.extend({ model: function() { return GiddyUp.Project.find( params.project_id); },
setupController: function(c, project) { c.set('content', project); } }); Sunday, January 20, 13
Template Actions Target the view/router with actions. Sunday, January 20,
13
<script type='text/x-handlebars' data-template-name='project'> {{#linkTo projects.show this}} {{name}} {{/linkTo}} </script> Sunday,
January 20, 13
<script type='text/x-handlebars' data-template-name='project'> <button {{action show this}}> {{name}} </button> </script>
Sunday, January 20, 13
GiddyUp.ProjectsRoute = Ember.Route.extend({ events: { show: function() { alert('cool story,
bro'); } } }); GiddyUp.ProjectsView = Ember.View.extend({ show: function() { alert('cool story, bro'); } }); GiddyUp.ProjectsController = Ember.ArrayController.extend({ show: function() { alert('cool story, bro'); } }); Sunday, January 20, 13
Ember-Data And Persistence Sunday, January 20, 13
Abstract Adapters REST, IndexedDb, etc. Sunday, January 20, 13
Asynchronous Proxy; asynchronously populated; lazily loaded. Sunday, January 20, 13
Identity Map Client side, in memory-cache. Sunday, January 20, 13
Transactional Accumulate updates; commit and rollback. Sunday, January 20, 13
State Managers Lifecycle management; isDirty, isClean, isSaving Sunday, January 20,
13
App.Person = DS.Model.extend({ firstName: DS.attr('string'), lastName: DS.attr('string'), birthday: DS.attr('date'), children:
DS.hasMany('App.Child'), fullName: function() { return this.get('firstName') + ' ' + this.get('lastName'); }.property('firstName', 'lastName') }); var person = App.Person.find(1); Sunday, January 20, 13
Demo https://github.com/cmeiklejohn/hack-harvard-2013-demo Sunday, January 20, 13
Questions? Sunday, January 20, 13