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
Aaron Chambers - Ember: when the lights go on
Search
Hey! Presents
April 07, 2015
Technology
0
210
Aaron Chambers - Ember: when the lights go on
Presented at Hey! #16 on 7th April, 2015.
Hey! Presents
April 07, 2015
Tweet
Share
More Decks by Hey! Presents
See All by Hey! Presents
Chris Taylor - Web matters
heypresents
0
380
Doug Winter - Everyone needs a strategy
heypresents
1
130
Paul Berwin - What IP? Whose IP?
heypresents
0
150
Jen Mak - On searching for purpose
heypresents
1
180
Malcolm Slade - The evolution of Google Organic Search
heypresents
0
180
Steve Clarkson - I can't teach you to be a writer
heypresents
0
150
Chris Compston - Design your own career
heypresents
0
220
Emily Cressey - Developers of habit
heypresents
0
180
Stefan McCready - It all started with an anchor tag
heypresents
0
190
Other Decks in Technology
See All in Technology
コンテナセキュリティの基本と脅威への対策
kyohmizu
3
710
The CloudCompare project by Dr. Daniel Girardeau-Montaut
kentaitakura
0
510
レガシーをぶっ壊せ。AEONで始めるDevRelの話 / Qiita Night 2024-2-22
aeonpeople
3
150
LLM とプロンプトエンジニアリング/チューターをビルドする / LLM and Prompt Engineering and Building Tutors
ks91
PRO
0
220
人間の尊厳、幸福、アクセシビリティ / 第116回「WEB TOUCH MEETING」アクセシビリティSP
nulabinc
PRO
2
180
HEXA OSINT CTF V3 作戦会議
meow_noisy
0
110
エンタープライズ環境下での Active Directory の運用 TIPS
tamaiyutaro
1
1.6k
普段有償でサポート業務をしているCSAが技術知見を無料で公開する理由
07jp27
1
640
o11y入門_外形監視を利用したWebアプリケーションへの最適なモニタリング_TechBrew
k5k
3
100
長期運用プロジェクトでのMySQLからTiDB移行の検証
colopl
2
700
開発生産性向上サービスを作るFindyが自分たちで開発生産性を爆上げした組織づくりの歩み / Findy's path to boosting its own development productivity 2024-04-17
ma3tk
3
350
2024/4/26 コンピュータ歴史博物館解説告知
toshi_atsumi
0
200
Featured
See All Featured
Teambox: Starting and Learning
jrom
128
8.4k
Git: the NoSQL Database
bkeepers
PRO
422
63k
What’s in a name? Adding method to the madness
productmarketing
PRO
15
2.6k
Mobile First: as difficult as doing things right
swwweet
216
8.6k
How To Stay Up To Date on Web Technology
chriscoyier
782
250k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
12
1.5k
Side Projects
sachag
451
41k
RailsConf 2023
tenderlove
2
530
Become a Pro
speakerdeck
PRO
10
4.5k
Web Components: a chance to create the future
zenorocha
305
41k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
501
140k
How STYLIGHT went responsive
nonsquared
92
4.8k
Transcript
ember:&when&the&lights&go&on @grandazz github.com/achambers
developing*since*2000 Javascript Ruby Java$and$Lotus$Notes
github.com/ember.cli/ember.cli.deploy
None
None
Wenguins
None
this%is%not an#ember#is#be(er#than#everything#else presenta(on
browser'dev'boiled'down (shamelessley)borrowed)from)@ryanflorence) interac(ng*with*data*stores rendering'data'to'ui responding*to*user*interac/on router&&&urls project(stuff:(file(organisa3on,(build(tools(etc
None
the$wenguins'$journey$with ember
lightbulb!moments
we#didn't#just#jump#in
we#needed#to validate the$switch
None
None
Service'Status
None
// app/assets/javascripts/application.js function bindViewMoreDetailsLinks() { $('.more-details').hide(); $('.view-more').click(function(e) { e.preventDefault(); var
$viewMoreLink = $(this); var $moreDetails = $viewMoreLink.parents('.issue').find('.more-details'); if ($moreDetails.is(':visible')) { $moreDetails.hide(); $viewMoreLink.text('More details'); } else { $moreDetails.show(); $viewMoreLink.text('Less details'); } $viewMoreLink.toggleClass('opened'); }); }
// app/assets/javascripts/application.js function toggleElementsForEditors() { $.ajax({ url: '/sessions/current', dataType: 'json',
success: function(data) { var loggedInStatus = data.logged_in; toggleNewIssueLink(loggedInStatus); toggleHeader(loggedInStatus); toggleAdditionalLinks(loggedInStatus); toggleSidebar(loggedInStatus); toggleFooter(loggedInStatus); toggleEditIssueLinks(loggedInStatus); toggleResolveIssueLinks(loggedInStatus); } }); }
// app/assets/javascripts/application.js function toggleHeader(loggedInStatus) { $('#skycom-masthead-wrapper').toggleClass('hidden', loggedInStatus); } function toggleAdditionalLinks(loggedInStatus)
{ $('.additional-links').toggleClass('hidden', loggedInStatus); } function toggleSidebar(loggedInStatus) { $('.sidebar').toggleClass('hidden', loggedInStatus); } function toggleFooter(loggedInStatus) { $('#skycom-footer-wrapper').toggleClass('hidden', loggedInStatus); } function toggleEditIssueLinks(loggedInStatus) { $('.btn.edit-issue').toggleClass('hidden', !loggedInStatus); } function toggleResolveIssueLinks(loggedInStatus) { $('.btn.resolve-issue').toggleClass('hidden', !loggedInStatus); }
None
data$based$ui$manipula.on
// app/views/issues/index.html.haml function microfilterCheck() { var deferred = $.Deferred(); $.getJSON('/sessions/current',
function(json) { if (json.logged_in) { deferred.resolve() } else { Hub.runMicrofilterTest() .done(function() { deferred.reject(); }) .fail(function() { deferred.resolve(); }); } }); return deferred; }
// app/views/issues/index.html.haml function restrictionCheck() { var deferred = $.Deferred(); $.getJSON('/customers/current',
function(json) { if (json.customer.has_debt_restriction) { deferred.reject('debt'); } else if (json.customer.has_high_spend_restriction) { deferred.reject('spend'); } else { deferred.resolve(); } }, function() { deferred.resolve(); }); return deferred; }
// app/views/issues/index.html.haml $(function() { var microfilterDeferred = microfilterCheck() var restrictionDeferred
= restrictionCheck() $.when(microfilterDeferred, restrictionDeferred).always(function() { var args = Array.prototype.slice.call(arguments); if (restrictionDeferred.state() == 'rejected') { if (args.indexOf('spend') !== -1) { $('.high-spend-restriction-alert').removeClass('hidden'); } else if (args.indexOf('debt') !== -1) { $('.debt-restriction-alert').removeClass('hidden'); } } else if (microfilterDeferred.state() == 'rejected') { $('.microfilter-alert').removeClass('hidden'); } showIssues(); }); });
then%the%very%next%commit...
// app/views/issues/index.html.haml $(function() { IssuesIndexController.init(); });
None
controllers
// app/assets/javasctipts/User.js var User = { isAnEditor: function() { var
deferred = $.Deferred(); $.ajax({ dataType: 'json', url: '/sessions/current', success: function(data) { deferred.resolve(data.logged_in); }, error: function() { deferred.reject(); } }); return deferred.promise(); } }
// app/assets/javascripts/Diagnostics.js var Diagnostics = { run: function() { //run
some diagnostics goodness } } // app/assets/javascripts/CBS.js var CBS = { run: function() { //run some monstrosity of a service, //return a massive payload we don't need //and take forever to do so } }
None
models & interac(ng*with*data*stores
// app/assets/javascripts/views/IssueView.js (function() { window.IssuesView = { render: function() {
this._showIssues(); this._toggleStatusMessage(); } // ...snip... }; })(); // app/assets/javascripts/views/DebtAlertView.js (function() { window.DebtAlertView = { render: function() { this._showAlert(); this._hideProducts(); this._hideSidebar(); this._informScreenReader(); } // ...snip... }; })();
None
views
{!-- app/assets/javascripts/templates/outages.hbs --}} {{#each outages}} <article class="issue"> <h3>{{description}}</h3> <p> <span
class="label">Date issue was reported</span> </br> <strong>{{startedOn}}</strong> </p> </article> {{/each}}
None
templa'ng
we#started#to#build#our#own#framework
we#started#to#build#our#own#framework BADLY
Use$a$framework,$or$don't.$Either$ way,$you$will. —"Someone"Awesome
conven&on'over'configura&on this.resource('posts', { path: '/posts' }) PostsRoute PostsController PostsView posts.hbs
no#more#globals var Diagnostics = { run: function() { // do
stuff } }; window.IssuesIndexController = { init: function() { // do stuff; } };
no#more#globals#,>#es2015#modules // app/controllers/go-issues.js export default Em.ArrayController.extend({ status: function() { //do
stuff }.property('hasProblem') }); // app/models/outage.js export default DS.Model.extend({ //attributes here }); // app/components/ss-accordion.js export default Em.Component.extend({ collapsed: false, //other properties here });
data$binding // models/tv_issue.js export default DS.Model.extend( name: DS.attr('string') ); //
controllers/tv_issues.js export default Em.ArrayController.extend({ }); <!-- templates/tv_issues.hbs --> <ul> <#each> <li>{{name}}</li> </each> </ul>
lightbulb(moments didn't&stop there
None
None
leave%your%assump-ons at#the#door
None
None
None
None
None
None
None
don't&fight&the&framework
If#something#feels#harder#than#it# should#be,#it#probably#is.#You're# probably#doing#it#wrong. —"Someone"Awesome
None
None
ui#error#logging
ui#error#logging Ember.onerror = handleError; Ember.RSVP.on('error', handleError); function handleError(error) { Em.$.ajax('/error',
{ type: 'POST', data: { stack: error.stack } }); }
None
None
separa&on)of ui#and#api
clearer&separa)on&between&data and$user$interac,on
think¬&of&your&api&in&terms&of&ui& interac2ons,&but&in&terms&of&data& and&rela2onships
your%app%is%a client'of'your'api
None
None
build&tools
build&tools lightening(fast(deployments
build&tools lightening(fast(deployments pact%file%tes*ng
Come%and%chat%to%me
Come%and%chat%to%me at#the#bar tonight
Come%and%chat%to%me Thursday)9th)April 2"Wellington"Place
Aaron&Chambers @grandazz github.com/achambers
any$ques)ons? @grandazz github.com/achambers
thanks'for'having'me