1. The document discusses various JavaScript frameworks and libraries including jQuery, Underscore.js, Backbone.js, and RequireJS.
2. It provides overviews of what each framework/library is used for such as DOM manipulation with jQuery, utility functions with Underscore, and model-view-controller architecture with Backbone.
3. The document also discusses concepts like asynchronous module definition that RequireJS uses to manage dependencies between JavaScript files.
2. HELLO
my name is
@AARONIUS · AARONHARDY.COM
Software Engineer, Adobe Digital Marketing Suite
We enable management, measurement, execution, and
optimization of digital advertising and marketing.
6. AccountInfo
(Group)
Header
(Group)
Menu
(ToggleButtonBar)
Main
Biography
(Application)
(Group)
Artist
(Group)
Similar Artists
(List)
Music Discography
(ViewStack) (DataGroup)
Discussion
(DataGroup)
7. ? Links ?
Basic Form Elements
Div
Image ? Bulleted Lists
?
? Span ?
8. <html>
<head>
<script>
buckets of vomit
buckets of vomit
buckets of vomit
buckets of vomit
buckets of vomit
</script>
</head>
<body>
buckets of vomit
buckets of vomit
buckets of vomit
buckets of vomit
buckets of vomit
</body>
</html>
15. Never build large apps
The secret to building large apps is NEVER build
large apps. Break up your applications into small
pieces. Then, assemble those testable, bite-sized
pieces into your big application.
– Justin Meyer
16. Admit what you
don’t know
The key is to acknowledge from the start that you
have no idea how this will grow. When you accept
that you don’t know everything, you begin to
design the system defensively.
– Nicholas Zakas
17. Add "use strict"; before code or at beginning of
function to help decrapify your code.
• Eliminates pitfalls by raising errors
• Improves JS engine optimization
• Prohibits syntax reserved for future JS versions
* Won’t be used in examples to save slide space
18. JSLint or JSHint.
• Run in IDE.
• Run on command line.
• Run in build scripts.
• Copy-paste into web interface.
• Use flags for configuration.
19. General community style:
• Names of directories and files shall be lowercase and
hyphens shall be used to separate words.
• Variable names shall be camelCase.
• Classes (functions) to be instantiated shall start with a
capital letter.
• Members intended to be private shall be prefixed with
an underscore.
20. Loose typing == more testing!
• JsTestDriver
• QUnit
• Jasmine
• Vows
• …and bucket-loads more
22. • Not an application framework!
• Abstracts the DOM
• Style
• Position
• Behavior
• Animation
• Creation/Removal
• AJAX requests
• Utilities for objects, arrays, strings, etc.
• “Framework” for UI widgets and utilities
23. Usage by Top Sites
http://trends.builtwith.com/javascript/jQuery
27. Old-school
• HTML buried in logic (hard to re-skin)
• Concatenation/escaping takes time and is error-prone
• IDE might not code-hint or color-code properly
• Boring and tedious
28. New-school
<script type="text/template" id="tweet-template">
<div>
<div style="float: left">
<img src="<%= avatar %>"/>
</div>
<div style="margin-left: 60px">
<p><%= username %></p>
<p><%= text %></p>
</div>
</div>
</script>
<script>
var tweet = {avatar: 'aaronius.jpg', alias: '@Aaronius',
text: 'Honey roasted peanuts rock my sox.'};
var template = _.template($('#tweet-template').html());
var html = template(tweet);
var element = $(html);
</script>
29. • Mustache.js
• Handlebars.js
• Jade
• Eco
• …and bucket-loads more.
Underscore.js templating is one of the best (though not as
full-featured) and is a dependency of Backbone.js. You can
use any templating engine.
36. Plain Old JavaScript Object
var book = {
title: 'A Tale of Two Cities',
author: 'Charles Dickens',
genre: 'historical',
publisher: 'Chapman & Hall'
};
How can another object know when one of book’s values
changes? It can’t!
37. Eventful Backbone.Model
var book = new Backbone.Model({
title: 'A Tale of Two Cities',
author: 'Charles Dickens',
genre: 'historical',
publisher: 'Chapman & Hall'
});
book.on('change:genre', function(model, genre) {
alert('genre for ' + model.get('title') +
' changed to ' + genre);
});
book.set({genre: 'social criticism'});
38. Extending Backbone.Model
var Book = Backbone.Model.extend({
…custom model logic…
});
var book = new Book({
title: 'A Tale of Two Cities',
author: 'Charles Dickens',
publisher: 'Chapman & Hall'
});
39. Persistence
HTTP Method URL Action
GET /books Retrieve all books
GET /books/10 Retrieve book with id == 10
POST /books Add a book
PUT /books/10 Update book with id == 10
DELETE /books/10 Delete book with id == 10
40. Persistence (save)
var Book = Backbone.Model.extend({
urlRoot: '/books'
});
var book = new Book({title: 'The Tragedy of the Commons'});
book.save();
41. Persistence (fetch)
var Book = Backbone.Model.extend({
urlRoot: '/books'
});
var book = new Book({id: 2});
var fetchSuccess = function() {
alert(book.get('title'));
};
book.fetch({success: fetchSuccess});
42.
43.
44. MODEL
layersOpen
characterOpen
magicWandOpen
colorOpen
infoOpen
45. And more…
• Validation
• Extracting native object
• Determine which attributes have changed
• And bucket-loads more…
47. Plain Old JavaScript Array:
var books = [book1, book2, book3, book4];
How can another object know when an item is added or
removed from this array? It can’t!
48. var goodEarth = new Backbone.Model();
var books = new Backbone.Collection();
books.on('add', function(book, books, options) {
alert('Book ' + book.get('title') + ' added at index ' +
options.at + '. ' + 'The collection now contains ' +
books.length + ' models.');
};
books.on('remove', function(book, books, options) {
alert('Book ' + book.get('title') + ' removed from index ' +
options.index);
}
books.add(goodEarth);
books.remove(goodEarth);
49. Event Pass-through
var books = new Backbone.Collection([taleOfTwoCities, goodEarth]);
books.on('change:title', function(book, title) {
alert('Book title changed from ' +
book.previous('title') + ' to ' + title);
});
goodEarth.set({title: 'Good Earth, The'});
50. Persistence (fetch)
var Books = Backbone.Collection.extend({
model: Book,
url: '/books'
});
var books = new Books();
books.fetch();
51. Underscore mix-ins
var titles = books.pluck('title');
each(), reduce(), find(), filter(), reject(), shuffle(), without()
and bucket-loads more!
52. And more…
• Sorting
• Resetting
• Retrieving model by id or index
• Custom loading and parsing
• …and bucket-loads more!
56. Stats
Model
Tweet
Model
Tweet
Tweet
Tweet
Collection
Tweet
Tweet
Tweet
Tweet
57. var Tweet = Backbone.Model.extend({ …view logic… });
var TweetRow = Backbone.View.extend({ …view logic… });
var tweet = new Tweet({
avatar: 'aaronius.jpg',
alias: '@Aaronius',
text: 'Honey roasted peanuts rock my sox.'
});
var row = new TweetRow({
model: tweet
});
62. Must we be restricted to working inside a few monstrous
spaghetti files? NO! Then why are they so prevalent?
• “That’s the way JavaScript has been done in the past.”
• “Loading many JavaScript files requires many HTTP
requests resulting in longer load times.”
• “Dependency management is hard in JavaScript.”
We can do better!
63. Old school
// What are the dependencies here!?
// What if a new employee had to re-order for some reason!?
<script src="script3.js"></script>
<script src="script1.js"></script>
<script src="script7.js"></script>
<script src="script6.js"></script>
<script src="script4.js"></script>
<script src="script5.js"></script>
<script src="script9.js"></script>
<script src="script8.js"></script>
<script src="script10.js"></script>
<script src="script2.js"></script>
74. Persistence with custom url pattern:
var Book = Backbone.Model.extend({
urlRoot: '/books',
url: function() {
return this.urlRoot + '?id=' + this.get('id');
}
})
var book = new Book({id: 2});
book.fetch();
75. var App = Backbone.View.extend({
initialize: function() {
this.render();
},
render: function() {
var tweet = new Tweet({
avatar: 'avatar.jpg',
username: '@Aaronius',
text: 'Honey roasted peanuts rock my sox.'
});
var row = new TweetRow({
model: tweet
});
this.$el.append(row.$el);
return this;
}
});
var app = new App({el: $('body')});
77. <script type="text/javascript">
$(function() {
var AppRouter = Backbone.Router.extend({
routes: {
"shirt/id/:id": "showShirt"
},
showShirt: function(id) {
alert('Show shirt with id ' + id);
}
});
var appRouter = new AppRouter();
Backbone.history.start();
});
</script>
<a href="#shirt/id/5">Shirt with id of 5</a><br>
<a href="#shirt/id/10">Shirt with id of 10</a><br>
<a href="#shirt/id/15">Shirt with id of 15</a><br>
78. <script type="text/javascript">
$(function() {
var AppRouter = Backbone.Router.extend({
routes: {
":product/:attribute/:value": "showProduct"
},
showProduct: function(product, attribute, value) {
alert('Show ' + product + ' where ' +
attribute + ' = ' + value + '.');
}
});
var appRouter = new AppRouter();
Backbone.history.start();
});
</script>
<a href="#shoe/size/12">Size 12 shoes</a><br>
<a href="#shirt/id/5">Shirt with id of 5</a><br>
<a href="#hat/color/black">Black hats</a>
79. var AppRouter = Backbone.Router.extend({
routes: {
":product/:attribute/:value": "showProduct"
}
});
var MyView = Backbone.View.extend({
initialize: function(options) {
options.router.on('route:showProduct',
this._showProduct);
}
_showProduct: function(product, attribute, value) {
alert('Update to show ' + product + ' where '
+ attribute + ' = ' + value + '.');
}
});
var appRouter = new AppRouter();
var view = new MyView({router: appRouter});
Backbone.history.start();
80. Fragment Identifier
• Using URLs in unintended ways
• Dependent on JavaScript
• Controversial
• Used by many popular sites
pushState aka HTML5 History
• The bee’s knees
• Allows changing of core url without changing pages
• Long-term solution
• Browser support lacking (guess which browser)
Notas del editor
Is the product part of a larger suite? What is the rest of the suite using?How hard would it be for us to refactor to another library?Is it a fad or popular for good reason?What’s the community like?How open-source is it?What’s the learning curve?How easy is it to hire developers that want to work with it?
How to handle many templates.
MV* Application FrameworkNon-prescriptive1200 lines of code (with comments)Extensible