© 2013 Adobe Systems Incorporated. All Rights Reserved. © 2013 Adobe Systems Incorporated. All Rights Reserved. JavaScript Paerns And Principles Aaron Hardy | Soware Engineer, Analytics
© 2013 Adobe Systems Incorporated. All Rights Reserved. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa!erns And Principles Aaron Hardy | So!ware Engineer, Analytics
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Architecture Misconceptions
2
jQuery is my architecture.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Architecture Misconceptions
3
jQuery is my architecture.
Websites are just the V in MVC.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Architecture Misconceptions
4
jQuery is my architecture.
Websites are just the V in MVC.
We’re already using MVC so we’re good.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Architecture Misconceptions
5
jQuery is my architecture.
Websites are just the V in MVC.
We’re already using MVC so we’re good.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns § Pa"erns Within MV*
6
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns § Pa"erns Within MV*
7
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Building Large Apps
8
#e secret to building large apps is NEVER build large apps. Break your application into small pieces. Assemble those testable, bite-sized pieces into your application. - Justin Meyer
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Modules Should Be…
9
Independent of other modules
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Modules Should Be…
10
Independent of other modules
Limited knowledge of the rest of the app
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Modules Should Be…
11
Independent of other modules
Reusable without refactoring
Limited knowledge of the rest of the app
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Modules Should Be…
12
Independent of other modules
Reusable without refactoring
Limited knowledge of the rest of the app
Functional when other modules break
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Modules Should Be…
13
Independent of other modules
Testable in isolation
Reusable without refactoring
Limited knowledge of the rest of the app
Functional when other modules break
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Possible Modules
Feed
Address Book
Chat Room
Menu
Shared Service
14
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns
§ Callback § Promise § Event Emi"er § Publish/Subscribe
§ Pa"erns Within MV*
15
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns
§ Callback § Promise § Event Emi"er § Publish/Subscribe
§ Pa"erns Within MV*
16
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Callbacks In Real Life
§ TODO: Picture of a fast food line while I explain how it demonstrates callbacks in real life.
17
CC Image Courtesy of #e Consumerist on Flickr
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Callback Example
var customer = { placeOrder: function() { restaurant.takeOrder('burger', this.onFoodReady); }, onFoodReady: function(food) { … } };
18
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Callback Example
var customer = { placeOrder: function() { restaurant.takeOrder('burger', this.onFoodReady); }, onFoodReady: function(food) { … } }; var restaurant = { takeOrder: function(order, foodReadyCallback) { // call foodReadyCallback(food) when food is ready } };
19
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Callback Key Points
Used to notify of completion of an asynchronous task Simple Efficient No libraries required
20
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns
§ Callback § Promise § Event Emi"er § Publish/Subscribe
§ Pa"erns Within MV*
21
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Promises In Real Life
22
© 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Promise Anatomy
23
takeSeatingRequest()
promise Promise then()
Customer Restaurant
© 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Promise Anatomy
24
takeSeatingRequest()
promise
Deferred resolve() reject() promise()
Promise then()
Customer Restaurant
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Promise Example
var customer = { requestSeating: function() { var promise = restaurant.takeSeatingRequest(); promise.then(this.sit); } sit: function() { … } };
25
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Promise Example
var customer = { requestSeating: function() { var promise = restaurant.takeSeatingRequest(); promise.then(this.sit); } sit: function(table) { … } }; var restaurant = { takeSeatingRequest: function() { var deferred = $.Deferred(); setTimeout(function() { deferred.resolve({seats: 4}); }, 5000); return deferred.promise(); } }; 26
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Promise Example
var customer = { requestSeating: function() { var promise = restaurant.takeSeatingRequest(); promise.then(this.sit); promise.fail(this.leave); } sit: function(table) { … }, leave: function() { … } }; var restaurant = { takeSeatingRequest: function() { var deferred = $.Deferred(); deferred.reject(); // Sorry, we’re closed! return deferred.promise(); } }; 27
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Asynchronous Sequence Using Callbacks
step1(function(value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { console.log('Success', value4); } } } }
28
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Asynchronous Sequence Using Callbacks
step1(function(value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { console.log('Success', value4); } } } }
29
PYRAMID OF DOOM
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Asynchronous Sequence Using Promises
step1() .then(step2) .then(step3) .then(step4) .then(function(value) { console.log('Success', value); });
30
Supported in jQuery 1.8+
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Try-catch In A Synchronous World
try { var value = step1(); value = step2(value); value = step3(value); value = step4(value); console.log('Success', value); } catch (error) { console.log('Failure', error); } finally { console.log('Time to clean up resources!'); }
31
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Asynchronous Try-catch Using Promises
step1() .then(step2) .then(step3) .then(step4) .then(function(value) { console.log('Success', value); }) .catch(function(error) { console.log('Failure', error); }) .finally(function() { console.log('Time to clean up resources!'); });
32
Supported in the Q promise library
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Asynchronous Parallel Using Callbacks
var requestsPending = 2; var onComplete = function(tweets) { requestsPending--; if (requestsPending == 0) { // Display tweets from both requests. } } loadTweets('#adobe', onComplete); loadTweets('#summit', onComplete);
33
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Asynchronous Parallel Using Callbacks
var requestsPending = 2; var onComplete = function(tweets) { requestsPending--; if (requestsPending == 0) { // Display tweets from both requests. } } loadTweets('#adobe', onComplete); loadTweets('#summit', onComplete);
34
o_O
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Asynchronous Parallel Using Promises
var adobePromise = loadTweets('#adobe'); var summitPromise = loadTweets('#summit'); $.when(adobePromise, summitPromise).then(displayTweets);
35
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Promise Key Points
Used to notify of completion of an asynchronous task Object passable now representing something to be determined in the future Great for sequential/parallel management Generally makes use of a third party library
36
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns
§ Callback § Promise § Event Emi!er § Publish/Subscribe
§ Pa"erns Within MV*
37
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Event Emi"ers In Real Life
§ TODO: Coupon text photo while I explain the similarities to event emi"ers.
38
CC Image Courtesy of Incase on Flickr
© 2013 Adobe Systems Incorporated. All Rights Reserved.
DOM Event Emi"er Example
var foo = document.getElementById('foo'); foo.addEventListener('click', function() { alert('bar'); }); foo.addEventListener('click', function() { alert('baz'); });
39
© 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Event Emi"er Example
var customer = { receiveCoupon: function(coupon) { … } };
40
© 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Event Emi"er Example
var customer = { receiveCoupon: function(coupon) { … } }; var restaurant = { offerCoupon: function(coupon) { $(this).trigger('couponAvailable', coupon); } };
41
© 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Event Emi"er Example
var customer = { receiveCoupon: function(coupon) { … } }; var restaurant = { offerCoupon: function(coupon) { $(this).trigger('couponAvailable', coupon); } }; $(restaurant).on('couponAvailable', customer.receiveCoupon);
42
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Event Emi"er Key Points
Noti$es of state change, user interaction, etc. Fires an event any number of times (possibly never) Native for DOM Arbitrary objects make use of a third-party library
43
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns
§ Callback § Promise § Event Emi"er § Publish/Subscribe
§ Pa"erns within MV*
44
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Anatomy
45
Pub/Sub Bus publish()
subscribe() unsubscribe()
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Anatomy
46
Pub/Sub Bus publish()
subscribe() unsubscribe()
Customer
bus.subscribe('couponAvailable', function() { … });
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Anatomy
47
Pub/Sub Bus publish()
subscribe() unsubscribe()
Restaurant Customer
bus.publish('couponAvailable', 'Buy 1 get 1 free');
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Example
48
Archive Report spam Delete Mark as unread
Android 4.2.1 vs iOS 6
Videos magically don’t have sound
If you could scale this to market it would be very valuable, no?
Clone SSD (Windows system partition) to HDD partition
JIRA help – Greenhopper + Scrum + Subtasks
Question se"ing up a VPN on $rewall
Shopping Carts
#e end of textbooks?
3 MeMail
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Example
49
Android 4.2.1 vs iOS 6
Videos magically don’t have sound
If you could scale this to market it would be very valuable, no?
Clone SSD (Windows system partition) to HDD partition
JIRA help – Greenhopper + Scrum + Subtasks
Question se"ing up a VPN on $rewall
Shopping Carts
#e end of textbooks?
0 MeMail
Archive Report spam Delete Mark as unread
Inbox Service
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Example
50
Android 4.2.1 vs iOS 6
Videos magically don’t have sound
If you could scale this to market it would be very valuable, no?
Clone SSD (Windows system partition) to HDD partition
JIRA help – Greenhopper + Scrum + Subtasks
Question se"ing up a VPN on $rewall
Shopping Carts
#e end of textbooks?
3 MeMail
Mark all as read
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Example
51
Android 4.2.1 vs iOS 6
Videos magically don’t have sound
If you could scale this to market it would be very valuable, no?
Clone SSD (Windows system partition) to HDD partition
JIRA help – Greenhopper + Scrum + Subtasks
Question se"ing up a VPN on $rewall
Shopping Carts
#e end of textbooks?
3 MeMail
bus.publish('selectedEmailsChanged', selectedEmails);
Bus
Mark all as read
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Example
52
Android 4.2.1 vs iOS 6
Videos magically don’t have sound
If you could scale this to market it would be very valuable, no?
Clone SSD (Windows system partition) to HDD partition
JIRA help – Greenhopper + Scrum + Subtasks
Question se"ing up a VPN on $rewall
Shopping Carts
#e end of textbooks?
3 MeMail
Archive Report spam Delete Mark as read
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Example
53
Android 4.2.1 vs iOS 6
Videos magically don’t have sound
If you could scale this to market it would be very valuable, no?
Clone SSD (Windows system partition) to HDD partition
JIRA help – Greenhopper + Scrum + Subtasks
Question se"ing up a VPN on $rewall
Shopping Carts
#e end of textbooks?
3 MeMail
Bus
Service
Archive Report spam Delete Mark as read
bus.publish('markAsReadRequested', emails);
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Example
54
Android 4.2.1 vs iOS 6
Videos magically don’t have sound
If you could scale this to market it would be very valuable, no?
Clone SSD (Windows system partition) to HDD partition
JIRA help – Greenhopper + Scrum + Subtasks
Question se"ing up a VPN on $rewall
Shopping Carts
#e end of textbooks?
3 MeMail
Bus
Service
bus.publish('markedAsRead', emails); Archive Report spam Delete Mark as read
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Example
55
Android 4.2.1 vs iOS 6
Videos magically don’t have sound
If you could scale this to market it would be very valuable, no?
Clone SSD (Windows system partition) to HDD partition
JIRA help – Greenhopper + Scrum + Subtasks
Question se"ing up a VPN on $rewall
Shopping Carts
#e end of textbooks?
2 MeMail
Archive Report spam Delete Mark as unread
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Key Points
Communication between modules Publishers and subscribers don’t address one another Provides excellent decoupling
56
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Which Pa"ern Should I Use?
57
Is the communication between modules?
Is it communicating a response to requested task?
Do you need to represent a future value?
Is sequence/parallel management important?
No Yes
No Yes
No Yes Event Emi!er
Callback Promise
Pub/Sub
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns § Pa!erns Within MV*
§ State Change Detection § Declarative Markup § View Manipulation § Dependency Injection
58
© 2013 Adobe Systems Incorporated. All Rights Reserved.
MVC
59
Model Represents data
or state
View Presentation and
user controls
Controller Logic between views
and models
© 2013 Adobe Systems Incorporated. All Rights Reserved.
MVP
60
Model Represents data
or state
View Presentation and
user controls
Presenter Logic between views
and models
© 2013 Adobe Systems Incorporated. All Rights Reserved.
MVVM
61
Model Represents data
or state
View Presentation and
user controls
ViewModel Logic between views
and models
© 2013 Adobe Systems Incorporated. All Rights Reserved.
MV*
62
Model Represents data
or state
View Presentation and
user controls *
© 2013 Adobe Systems Incorporated. All Rights Reserved.
MV* Frameworks
63
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Comparison At A Glance
64
Requires Underscore/LoDash and jQuery/Zepto
6K + 4K (Underscore) + 28K (jQuery 2.0) gzipped
Non-prescriptive
Extensions add functionality and/or prescription
Eventful proxy models
Used in tandem with a template engine
Binding available through extensions
Dependency injection available through extensions
jqLite built-in
29K gzipped
Prescriptive
Intended to be a full(er) stack out of the box
Dirty checking
Custom HTML tags and a"ributes (directives)
Two-way data-binding built-in
Dependency injection built-in
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns § Pa"erns Within MV*
§ State Change detection § Declarative Markup § View Manipulation § Dependency Injection
65
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Proxy Models
66
var book = { title: 'A Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical', }; var bookView = new BookView(book); book.genre = 'Social Criticism';
How does BookView know that the book’s genre changed?
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Proxy Models
67
var book = { title: 'A Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical', }; var bookView = new BookView(book); book.genre = 'Social Criticism'; bookView.genreChanged(); We could manually tell it…
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Proxy Models
68
var book = { title: 'A Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical', }; var bookView = new BookView(book); book.genre = 'Social Criticism'; bookView.genreChanged(); We could manually tell it…
but not without creating a tangled mess.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Proxy Models
69
Let’s wrap our object in a proxy.
var book = new Backbone.Model({ title: 'A Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical', }); var bookView = new BookView(book); book.set({genre: 'Social Criticism'});
Now we must use the proxy functions. (Until ECMAScript Harmony!)
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Proxy Models
70
Meanwhile, inside BookView… book.on('change:genre', onChange);
var book = new Backbone.Model({ title: 'A Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical', }); var bookView = new BookView(book); book.set({genre: 'Social Criticism'});
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Proxy Models
71
We do something similar for arrays.
var books = new Backbone.Collection([ book1, book2, book3 ]); var booksView = new BooksView(books); books.add(book4);
books.on('add', onAdd);
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Dirty Checking
72
Meanwhile inside BookView…
var book = { title: 'A Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical', }; …pass book to BookView… book.genre = 'Social Criticism';
$scope.book = book; $scope.$watch('book', function() { console.log('changed!'); }, true);
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Dirty Checking
73
User Click
Change Object
Watchers: Is the object different than last time?
Yes. React.
Watchers: Is the object different than last time?
No
Digest Cycle Triggered automatically on user interaction, h"p responses, etc. Can be manually triggered.
Trigger Wait
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns § Pa"erns within MV*
§ State Change Detection § Declarative Markup § View Manipulation § Dependency Injection
74
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Templates
<script id="users-template" type="text/x-handlebars-template"> <ul> {{#users}} <li>Name: {{name}}, Email: {{email}}</li> {{/users}} </ul> </script>
75
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Templates
var data = { users: [ { name: 'John', email: '[email protected]' }, { name: 'Jane', email: '[email protected]' } ] }; var source = $('#users-template').html(); var template = Handlebars.compile(source); var html = template(data); $('body').html(html);
76
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Templates
<body> <ul> <li>Name: John, Email: [email protected]</li> <li>Name: Jane, Email: [email protected]</li> </ul> </body>
77
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Directives
<ul> <li ng-repeat="user in users"> Username: {{user.name}}, Email: {{user.email}} </li> </ul> function MyController($scope) { $scope.users = [ {name: 'John', email: '[email protected]'}, {name: 'Jane', email: '[email protected]'} ]; }
78
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns § Pa"erns Within MV*
§ State Change Detection § Declarative Markup § View Manipulation § Dependency Injection
79
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Responding To And Updating View
Name: <input type="text" class="name-in"> <h1>Hello <span class="name-out"></span></h1> Backbone.View.extend({ events: { 'keyup .name-in': 'onNameChange' }, onNameChange: function(event) { // TODO: Optimize var name = $(event.target).val(); this.$('.name-out').text(name); } });
80
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Binding
Name: <input type="text" ng-model="yourName"> <h1>Hello {{yourName}}</h1>
81
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns § Pa"erns within MV*
§ State change detection § Declarative Markup § View Manipulation § Dependency Injection
82
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Without Dependency Injection
83
var TweetStream = function() { this.twitter = new TwitterService(); }; TweetStream.prototype.showTweets = function() { var tweets = this.twitter.getTweets(); … }; var stream = new TweetStream(); stream.showTweets();
© 2013 Adobe Systems Incorporated. All Rights Reserved.
With Dependency Injection
84
var TweetStream = function(twitter) { this.twitter = twitter; }; TweetStream.prototype.showTweets = function() { var tweets = this.twitter.getTweets(); … }; var twitter = new TwitterService(); var stream = new TweetStream(twitter); stream.showTweets();
We inverted control of the Twi!erService construction.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Inversion of Control Container
When rank is requested, provide the value 1337. When twi!er is requested, provide a new instance of Twi!erService. When dialog is requested, provide the SearchDialog constructor. When logger is requested, provide a singleton instance of AsyncLogger. When chat is requested, provide whatever is returned from chatFactory.
85
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Dependency Injection
86
var MyController = function($http, $scope) { $http.get('http://github.com/…') .success(function(commits) { $scope.commits = commits; }); }; $injector.instantiate(MyController);
How does $injector know what to inject for $h!p and $scope?
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Dependency Injection
87
var MyController = function($http, $scope) { $http.get('http://github.com/…') .success(function(commits) { $scope.commits = commits; }); }; $injector.instantiate(MyController);
How does $injector know what to inject for $h!p and $scope? By using toString() and some well-cra$ed regex.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Dependency Injection
88
var MyController = function($http, $scope) { $http.get('http://github.com/…') .success(function(commits) { $scope.commits = commits; }); }; $injector.instantiate(MyController);
What if we reverse the parameter order?
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Dependency Injection
89
var MyController = function($scope, $http) { $http.get('http://github.com/…') .success(function(commits) { $scope.commits = commits; }); }; $injector.instantiate(MyController);
What if we reverse the parameter order? It still works!
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Dependency Injection
90
var MyController = function(a, b) { a.get('http://github.com/…') .success(function(c) { b.commits = c; }); }; $injector.instantiate(MyController);
What if we reverse the parameter order? It still works! Until we minify it.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Dependency Injection
91
var MyController = function(a, b) { a.get('http://github.com/…') .success(function(c) { b.commits = c; }); }; MyController.$inject = ['$http', '$scope']; $injector.instantiate(MyController);
What if we reverse the parameter order? It still works! Until we minify it. %en we have to annotate.
© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Pa"erns And Principles
§ Modularity § Communication Pa"erns § Pa"erns Within MV*
92
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Promise Implementations
93
Q
jQuery
rsvp.js
kriskowal/q
jquery/jquery
tildeio/rsvp.js
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Implementations
94
Postal.js
AmplifyJS
PubSubJS
postaljs/postal.js
appendto/amplify
mroderick/pubsubjs
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Inversion of Control and Dependency Injection
95
Article by Martin Fowler h"p://martinfowler.com/articles/injection.html Wikipedia source of truth h"p://en.wikipedia.org/wiki/Dependency_injection Lightweight inversion of control container with examples h"ps://github.com/Aaronius/injectorjs
© 2013 Adobe Systems Incorporated. All Rights Reserved.
Inversion of Control and Dependency Injection
96
Article by Martin Fowler h"p://martinfowler.com/articles/injection.html Wikipedia source of truth h"p://en.wikipedia.org/wiki/Dependency_injection Lightweight inversion of control container with examples h"ps://github.com/Aaronius/injectorjs