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
Building Ambitious Web Applications With Ember.js
Search
Christopher Meiklejohn
November 09, 2012
Programming
15
1.3k
Building Ambitious Web Applications With Ember.js
Web Unleashed 2012 Presentation
Christopher Meiklejohn
November 09, 2012
Tweet
Share
More Decks by Christopher Meiklejohn
See All by Christopher Meiklejohn
Towards a Solution to the Red Wedding Problem
cmeiklejohn
0
400
Language Support for Cloud-Scale Distributed Systems
cmeiklejohn
0
530
Towards a Systems Approach to Distributed Programming
cmeiklejohn
3
350
Scaling a Startup with a 21st Century Programming Language
cmeiklejohn
0
410
Practical Evaluation of the Lasp Programming Model at Scale
cmeiklejohn
4
2.7k
Just-Right Consistency - Closing the CAP Gap
cmeiklejohn
3
260
Declarative, Convergent, Edge Computation
cmeiklejohn
1
200
Just-Right Consistency - Closing the CAP Gap
cmeiklejohn
3
1.3k
A Certain Tendency of the Database Community
cmeiklejohn
0
460
Other Decks in Programming
See All in Programming
PipeCDのプラグイン化で目指すところ
warashi
1
300
Android 16KBページサイズ対応をはじめからていねいに
mine2424
0
430
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
3
790
レトロゲームから学ぶ通信技術の歴史
kimkim0106
0
110
「テストは愚直&&網羅的に書くほどよい」という誤解 / Test Smarter, Not Harder
munetoshi
0
200
Claude Code + Container Use と Cursor で作る ローカル並列開発環境のススメ / ccc local dev
kaelaela
12
7k
PicoRuby on Rails
makicamel
2
140
AI時代の『改訂新版 良いコード/悪いコードで学ぶ設計入門』 / ai-good-code-bad-code
minodriven
23
9.5k
たった 1 枚の PHP ファイルで実装する MCP サーバ / MCP Server with Vanilla PHP
okashoi
1
300
PostgreSQLのRow Level SecurityをPHPのORMで扱う Eloquent vs Doctrine #phpcon #track2
77web
2
580
マッチングアプリにおけるフリックUIで苦労したこと
yuheiito
0
190
チームのテスト力を総合的に鍛えて品質、スピード、レジリエンスを共立させる/Testing approach that improves quality, speed, and resilience
goyoki
5
1.1k
Featured
See All Featured
Side Projects
sachag
455
42k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Embracing the Ebb and Flow
colly
86
4.8k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Producing Creativity
orderedlist
PRO
346
40k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Facilitating Awesome Meetings
lara
54
6.5k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Being A Developer After 40
akosma
90
590k
How to Think Like a Performance Engineer
csswizardry
25
1.7k
Transcript
Building Ambitious Web Applications With Ember.js Christopher Meiklejohn @cmeik Friday,
November 9, 12
An Introduction To Ember.js Christopher Meiklejohn @cmeik Friday, November 9,
12
@cmeik Friday, November 9, 12
Basho Friday, November 9, 12
What is Ember.js? Friday, November 9, 12
MVC Structure Friday, November 9, 12
Data Bindings Friday, November 9, 12
Computed Properties Friday, November 9, 12
Data Bound Declarative Templates Friday, November 9, 12
State Managers Friday, November 9, 12
Declarative Router Friday, November 9, 12
Run Loop Friday, November 9, 12
Ember Data Friday, November 9, 12
Let’s get started! Friday, November 9, 12
Object Model Friday, November 9, 12
Objects and Classes Friday, November 9, 12
App.Person = Ember.Object.extend({ say: function(thing) { alert(thing); } }); var
person = App.Person.create(); person.say("Hello Joe."); Friday, November 9, 12
Observers Friday, November 9, 12
App.Person = Ember.Object.extend({ fullNameChanged: function() { console.log('fullNameChanged!'); }.observes('fullName') }); Friday,
November 9, 12
App.Person = Ember.Object.extend({ childMarried: function() { console.log('ERMAHGERD!'); }.observes('children.@each.isMarried') }); Friday,
November 9, 12
Mixins Friday, November 9, 12
App.Editable = Ember.Mixin.create({ edit: function() { this.set('isEditing', true); }, isEditing:
false }); App.CommentView = Ember.View.extend( App.Editable, { template: Ember.Handlebars.compile('...') }); Friday, November 9, 12
Computed Properties Friday, November 9, 12
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'); Friday, November 9, 12
Controllers Friday, November 9, 12
Controllers ObjectController ArrayController Controller Friday, November 9, 12
Ember.ArrayController.create({ content: [object1, object2] }); Ember.ObjectController.create({ content: object3 }); Friday,
November 9, 12
Controllers ObjectController ArrayController Controller Friday, November 9, 12
Controllers ObjectProxy ArrayProxy Friday, November 9, 12
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'); Friday, November 9, 12
App.presidentController = Ember.ObjectController.create({ contentBinding: 'App.president' }); App.presidentController.get('fullName'); Friday, November 9,
12
Views Friday, November 9, 12
App.PresidentView = Ember.View.create({ templateName: 'president', contentBinding: 'App.president' }); <script type='text/x-handlebars'
data-template-name='president'> {{fullName}} </script> Friday, November 9, 12
Run Loop Deferred rendering; change propagation; coalescing. Friday, November 9,
12
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'); Friday, November 9, 12
The Router and Application Structure Friday, November 9, 12
Application as a series of states Friday, November 9, 12
Application as a series of states hierarchy of views Friday,
November 9, 12
Friday, November 9, 12
Friday, November 9, 12
Friday, November 9, 12
Friday, November 9, 12
Nested Outlets Outlet as Controller/View Pair Friday, November 9, 12
<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}} Friday, November 9, 12
<div class="navbar" style="margin-bottom:0"> <div class="navbar-inner"> <a class="brand" href="#">GiddyUp</a> {{outlet projects}}
</div> </div> {{outlet scorecards}} {{outlet}} Friday, November 9, 12
State Machine Application as a series of states and transitions.
Friday, November 9, 12
GiddyUp.Router = Ember.Router.extend({ root: Ember.Route.extend({ index: Ember.Route.extend({ route: '/', redirectsTo:
'projects.index' }), // next slide }) }); Friday, November 9, 12
projects: Ember.Route.extend({ route: '/projects', // next slide index: Ember.Route.extend({ route:
'/' }), show: Ember.Route.extend({ route: '/:project_id' }); }); Friday, November 9, 12
connectOutlets: function(router, context) { router.get('applicationController'). connectOutlet('projects', 'projects', GiddyUp.Project.find()); }, Friday,
November 9, 12
Serialization The URL as a serialization of application state. Friday,
November 9, 12
projects: Ember.Route.extend({ route: '/projects', index: Ember.Route.extend({ route: '/' }), show:
Ember.Route.extend({ route: '/:project_id' }); }); /projects/ Friday, November 9, 12
projects: Ember.Route.extend({ route: '/projects', index: Ember.Route.extend({ route: '/' }), show:
Ember.Route.extend({ route: '/:project_id' }) }); /projects/:project_id Friday, November 9, 12
serialize: function(router, context) { return context.get('id'): } Friday, November 9,
12
Deserialization Deserialize the URL to a position in the state
chart. Friday, November 9, 12
projects: Ember.Route.extend({ route: '/projects', index: Ember.Route.extend({ route: '/' }), show:
Ember.Route.extend({ route: '/:project_id' }) }); /projects/:project_id Friday, November 9, 12
deserialize: function(router, params) { var projectId = params.project_id; return GiddyUp.Project.find(projectId);
} Friday, November 9, 12
Template Actions Target the router with actions. Friday, November 9,
12
projects: Ember.Route.extend({ route: '/projects', showProject: Ember.Router. transitionTo('projects.show'), index: Ember.Route.extend({ route:
'/' }), show: Ember.Route.extend({ index: '/:project_id' }) }); Friday, November 9, 12
<script type='text/x-handlebars' data-template-name='project'> <a {{action showProject this href=true}} >{{name}}</a> </script>
Friday, November 9, 12
Ember-Data And Persistence Friday, November 9, 12
Abstract Adapters REST, IndexedDb, etc. Friday, November 9, 12
Asynchronous Proxy; asynchronously populated; lazily loaded. Friday, November 9, 12
Identity Map Client side, in memory-cache. Friday, November 9, 12
Transactional Accumulate updates; commit and rollback. Friday, November 9, 12
State Managers Lifecycle management; isDirty, isClean, isSaving Friday, November 9,
12
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); Friday, November 9, 12
Tooling Friday, November 9, 12
QUnit https://github.com/emberjs/bootstrap Friday, November 9, 12
Ember-Rails https://github.com/emberjs/ember-rails Friday, November 9, 12
Iridium https://github.com/radiumsoftware/iridium Friday, November 9, 12
Rebar Plugins https://github.com/cmeiklejohn Friday, November 9, 12
Questions? Friday, November 9, 12