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
The Modern JavaScript Application
Search
Andy Appleton
October 16, 2012
Technology
5
540
The Modern JavaScript Application
A talk at FOWA London
Andy Appleton
October 16, 2012
Tweet
Share
More Decks by Andy Appleton
See All by Andy Appleton
Done is better than perfect
appltn
0
480
Rage against the state machine
appltn
1
390
Modular UI with (Angular || Ember)
appltn
0
100
Building web apps with Express
appltn
4
460
Object Creation Pattern Performance
appltn
1
670
Introducing Mint Source
appltn
1
380
Other Decks in Technology
See All in Technology
LLM開発・活用の舞台裏@2024.04.25
yushin_n
3
1.3k
EM完全に理解した と思ったけど、 やっぱり何も分からなかった話 / EM Night Fukuoka #1
hirutas
0
290
2023年度にEMとして頑張ったこと
ikefukurou777
0
100
Building a RAG-poweredAI chat appwith Python and VS Code
pamelafox
0
160
「スニダン」開発組織の構造に込めた意図 ~組織作りはパッションや政治ではない!~
rinchsan
4
620
生産性向上チームの紹介
cybozuinsideout
PRO
1
930
Next.js に疲れた私は Vue3 に癒やされた
akagire
0
140
コードファーストの考え方。 Amplify Gen2から学ぶAWS次世代のWeb開発体験
yoshiitaka
2
390
Handling focus in 2024
tahia910
0
240
プロンプトエンジニアリングでがんばらない-Agentic Workflow へ-近藤憲児
kenjikondobai
6
1.2k
Python と Snowflake はズッ友だょ!~ Snowflake の Python 関連機能をふりかえる ~
__allllllllez__
2
140
Rustで「プリズモイダル法」を利用して「土量計算」をガチでやる
nokonoko1203
1
310
Featured
See All Featured
GraphQLとの向き合い方2022年版
quramy
33
12k
Gamification - CAS2011
davidbonilla
77
4.6k
RailsConf 2023
tenderlove
9
560
What the flash - Photography Introduction
edds
64
11k
Building an army of robots
kneath
300
41k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
9
1.3k
Adopting Sorbet at Scale
ufuk
69
8.6k
Designing with Data
zakiwarfel
96
4.8k
Product Roadmaps are Hard
iamctodd
45
9.7k
Raft: Consensus for Rubyists
vanstee
133
6.3k
Web development in the modern age
philhawksworth
203
10k
Fashionably flexible responsive web design (full day workshop)
malarkey
398
65k
Transcript
The Modern JavaScript Application Andy Appleton @appltn http://appleton.me
JS is growing up we are doing more and more
with it and we need more robust tools
$(function(){ $('.thing').on('click', function(ev){ ev.preventDefault(); var $link = $(this) $.get($link.attr('href'), function(data)
{ $link.fadeOut(function(){ $('body').append(data); }); }); }); });
We can do better other languages have rich sets of
tools and patterns, we can too!
None
None
None
Models var Person = Backbone.Model.extend({ sayName: function(){ return this.get('name'); }
}); var andy = new Person({ name: 'Andy' }); andy.sayName(); // => 'Andy'
Collections var People = Backbone.Collection.extend({ sayNames: function(){ return this.map(function(model){ return
model.get('name'); }).join(', '); } });
Views var PersonView = Backbone.view.extend({ render: function(){ this.el.innerHTML = this.model.get('name');
} });
Tools
None
None
Modules defined chunks of code which list their own dependencies
Our Model From Earlier define(['path/to/dependency'], function(dependency){ return Backbone.Model.extend({ // Adding
methods and properties }); });
Alternative Syntax define(function(require){ var dependency = require('path/to/dep'); return Backbone.Model.extend({ //
Adding methods and properties }); });
Structure & Conventions Split each module into a separate file
None
The Requests!
The Requests! The Humanity!
r.js The RequireJS build tool
$ node r.js -o config.js Concatenate & minify JS into
a single file Concatenate & minify CSS via @import
None
Templating
None
http://handlebarsjs.com/
var input = '<h1>{{ name }}</h1>'; var templateFn = Handlebars.compile(input);
var output = templateFn({ name: 'Andy' }); // => '<h1>Andy</h1>'
var input = ' <article>\ <header>\ <h1>{{title}}</h1>\ by {{author}} on
{{date}}\ </header>\ {{content}}\ </article>\ ';
index.html <script type="text/template" id="tpl-name"> <article> <header> <h1>{{title}}</h1> ...etc </script> my-view.js
var input = $('#tpl-name').text(); // ...compile etc
https://github.com/SlexAxton/require-handlebars-plugin
my-view.js define(function(require){ var templateFn = require('hbs!path/to/tpl'); // View now has
access to compiled template // function }); post-template.hbs <article> <header> <h1>{{title}}</h1> ...etc
my-view.js define(function(require){ var templateFn = require('hbs!path/to/tpl'); // View now has
access to compiled template // function }); post-template.hbs <article> <header> <h1>{{title}}</h1> ...etc
Handy Patterns
Mediator A central object to publish and subscribe to global
events
var mediator = _.clone(Backbone.Events); mediator.on('eventname', function(args){ console.log(args); }); mediator.trigger('eventname', 'sausages');
// => 'sausages' mediator.off('eventname');
Model Caching sharing model instances across views
define(function(require){ var _cache = {}, Model = Backbone.Model.extend(); Model.create =
function(opts) { if (opts.id && !_cache[opts.id]) { _cache[opts.id] = new Model(opts); } return _cache[opts.id]; }; return Model; });
define(function(require){ var _cache = {}, Model = Backbone.Model.extend(); Model.create =
function(opts) { if (opts.id && !_cache[opts.id]) { _cache[opts.id] = new Model(opts); } return _cache[opts.id]; }; return Model; });
define(function(require){ var _cache = {}, Model = Backbone.Model.extend(); Model.create =
function(opts) { if (opts.id && !_cache[opts.id]) { _cache[opts.id] = new Model(opts); } return _cache[opts.id]; }; return Model; });
Unit Testing
None
http://pivotal.github.com/jasmine/
var Person = Backbone.Model.extend({ sayName: function(){ return this.get('name'); } });
Our Model From Earlier (again)
describe('Person model', function(){ describe('#sayName', function(){ it('returns `name` attribute', function(){ var
person = new Person({ name: 'Andy' }); expect(person.sayName()).toEqual('Andy'); }); }); });
None
Automation
Grunt JS command line build tool http://gruntjs.com/
None
+ http://phantomjs.org/
None
None
None
https://github.com/mrappleton/jasmine-examples
None
Andy Appleton @appltn http://appleton.me