Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Client Side Applications with Ember.js
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Christopher Meiklejohn
January 20, 2013
Programming
760
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
440
Language Support for Cloud-Scale Distributed Systems
cmeiklejohn
0
590
Towards a Systems Approach to Distributed Programming
cmeiklejohn
3
390
Scaling a Startup with a 21st Century Programming Language
cmeiklejohn
0
430
Practical Evaluation of the Lasp Programming Model at Scale
cmeiklejohn
4
2.8k
Just-Right Consistency - Closing the CAP Gap
cmeiklejohn
3
320
Declarative, Convergent, Edge Computation
cmeiklejohn
1
240
Just-Right Consistency - Closing the CAP Gap
cmeiklejohn
3
1.4k
A Certain Tendency of the Database Community
cmeiklejohn
0
500
Other Decks in Programming
See All in Programming
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
320
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
180
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
430
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
180
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
410
テーブルをDELETEした
yuzneri
0
120
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
430
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
2
140
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
160
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
190
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
220
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
460
Featured
See All Featured
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
430
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
250
A Modern Web Designer's Workflow
chriscoyier
698
190k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.7k
Skip the Path - Find Your Career Trail
mkilby
1
170
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
360
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
310
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
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