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
Christopher Meiklejohn
January 20, 2013
Programming
15
730
Client Side Applications with Ember.js
Hack Harvard 2013
Christopher Meiklejohn
January 20, 2013
Tweet
Share
More Decks by Christopher Meiklejohn
See All by Christopher Meiklejohn
Towards a Solution to the Red Wedding Problem
cmeiklejohn
0
360
Language Support for Cloud-Scale Distributed Systems
cmeiklejohn
0
490
Towards a Systems Approach to Distributed Programming
cmeiklejohn
3
300
Scaling a Startup with a 21st Century Programming Language
cmeiklejohn
0
380
Practical Evaluation of the Lasp Programming Model at Scale
cmeiklejohn
4
2.7k
Just-Right Consistency - Closing the CAP Gap
cmeiklejohn
3
240
Declarative, Convergent, Edge Computation
cmeiklejohn
1
190
Just-Right Consistency - Closing the CAP Gap
cmeiklejohn
3
1.3k
A Certain Tendency of the Database Community
cmeiklejohn
0
430
Other Decks in Programming
See All in Programming
watsonx.ai Dojo #4 生成AIを使ったアプリ開発、応用編
oniak3ibm
PRO
1
120
Amazon Qを使ってIaCを触ろう!
maruto
0
410
Nurturing OpenJDK distribution: Eclipse Temurin Success History and plan
ivargrimstad
0
920
Make Impossible States Impossibleを 意識してReactのPropsを設計しよう
ikumatadokoro
0
170
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
330
PHP でアセンブリ言語のように書く技術
memory1994
PRO
1
170
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
What’s New in Compose Multiplatform - A Live Tour (droidcon London 2024)
zsmb
1
470
flutterkaigi_2024.pdf
kyoheig3
0
110
LLM生成文章の精度評価自動化とプロンプトチューニングの効率化について
layerx
PRO
2
190
色々なIaCツールを実際に触って比較してみる
iriikeita
0
330
Duckdb-Wasmでローカルダッシュボードを作ってみた
nkforwork
0
130
Featured
See All Featured
Side Projects
sachag
452
42k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
Building Your Own Lightsaber
phodgson
103
6.1k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
Put a Button on it: Removing Barriers to Going Fast.
kastner
59
3.5k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
410
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
Adopting Sorbet at Scale
ufuk
73
9.1k
Teambox: Starting and Learning
jrom
133
8.8k
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