Contenu connexe
Similaire à JavaScript Patterns and Principles
Similaire à JavaScript Patterns and Principles (20)
JavaScript Patterns and Principles
- 1. © 2013 Adobe Systems Incorporated. All Rights Reserved.© 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
Aaron Hardy | Software Engineer, Analytics
- 2. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Architecture Misconceptions
2
jQuery is
my architecture.
- 3. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Architecture Misconceptions
3
jQuery is
my architecture.
Websites are
just the V in MVC.
- 4. © 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.
- 5. © 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.
- 6. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Patterns Within MV*
6
- 7. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Patterns Within MV*
7
- 8. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Building Large Apps
8
The 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
- 9. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Modules Should Be…
9
Independent
of other modules
- 10. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Modules Should Be…
10
Independent
of other modules
Limited knowledge
of the rest of the app
- 11. © 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
- 12. © 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
- 13. © 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
- 14. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Possible Modules
Feed
Address Book
Chat Room
Menu
Shared Service
14
- 15. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Callback
§ Promise
§ Event Emitter
§ Publish/Subscribe
§ Patterns Within MV*
15
- 16. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Callback
§ Promise
§ Event Emitter
§ Publish/Subscribe
§ Patterns Within MV*
16
- 17. © 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 The Consumerist on Flickr
- 18. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Callback Example
var customer = {
placeOrder: function() {
restaurant.takeOrder('burger', this.onFoodReady);
},
onFoodReady: function(food) { … }
};
18
- 19. © 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
- 20. © 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
- 21. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Callback
§ Promise
§ Event Emitter
§ Publish/Subscribe
§ Patterns Within MV*
21
- 22. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Promises In Real Life
22
- 23. © 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Promise Anatomy
23
takeSeatingRequest()
promise Promise
then()
Customer Restaurant
- 24. © 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Promise Anatomy
24
takeSeatingRequest()
promise
Deferred
resolve()
reject()
promise()
Promise
then()
Customer Restaurant
- 25. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Promise Example
var customer = {
requestSeating: function() {
var promise = restaurant.takeSeatingRequest();
promise.then(this.sit);
}
sit: function() { … }
};
25
- 26. © 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
- 27. © 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
- 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);
}
}
}
}
28
- 29. © 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
- 30. © 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+
- 31. © 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
- 32. © 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
- 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);
33
- 34. © 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
- 35. © 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
- 36. © 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
- 37. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Callback
§ Promise
§ Event Emitter
§ Publish/Subscribe
§ Patterns Within MV*
37
- 38. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Event Emitters In Real Life
§ TODO: Coupon text photo while I explain the similarities to event emitters.
38
CC Image Courtesy of Incase on Flickr
- 39. © 2013 Adobe Systems Incorporated. All Rights Reserved.
DOM Event Emitter Example
var foo = document.getElementById('foo');
foo.addEventListener('click', function() {
alert('bar');
});
foo.addEventListener('click', function() {
alert('baz');
});
39
- 40. © 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Event Emitter Example
var customer = {
receiveCoupon: function(coupon) { … }
};
40
- 41. © 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Event Emitter Example
var customer = {
receiveCoupon: function(coupon) { … }
};
var restaurant = {
offerCoupon: function(coupon) {
$(this).trigger('couponAvailable', coupon);
}
};
41
- 42. © 2013 Adobe Systems Incorporated. All Rights Reserved.
jQuery Event Emitter Example
var customer = {
receiveCoupon: function(coupon) { … }
};
var restaurant = {
offerCoupon: function(coupon) {
$(this).trigger('couponAvailable', coupon);
}
};
$(restaurant).on('couponAvailable', customer.receiveCoupon);
42
- 43. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Event Emitter Key Points
Notifies 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
- 44. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Callback
§ Promise
§ Event Emitter
§ Publish/Subscribe
§ Patterns within MV*
44
- 45. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Anatomy
45
Pub/Sub Bus
publish()
subscribe()
unsubscribe()
- 46. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Anatomy
46
Pub/Sub Bus
publish()
subscribe()
unsubscribe()
Customer
bus.subscribe('couponAvailable', function() { … });
- 47. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Anatomy
47
Pub/Sub Bus
publish()
subscribe()
unsubscribe()
RestaurantCustomer
bus.publish('couponAvailable', 'Buy 1 get 1 free');
- 48. © 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 setting up a VPN on firewall
Shopping Carts
The end of textbooks?
3MeMail
- 49. © 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 setting up a VPN on firewall
Shopping Carts
The end of textbooks?
0MeMail
Archive Report spam Delete Mark as unread
Inbox
Service
- 50. © 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 setting up a VPN on firewall
Shopping Carts
The end of textbooks?
3MeMail
Mark all as read
- 51. © 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 setting up a VPN on firewall
Shopping Carts
The end of textbooks?
3MeMail
bus.publish('selectedEmailsChanged', selectedEmails);
Bus
Mark all as read
- 52. © 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 setting up a VPN on firewall
Shopping Carts
The end of textbooks?
3MeMail
Archive Report spam Delete Mark as read
- 53. © 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 setting up a VPN on firewall
Shopping Carts
The end of textbooks?
3MeMail
Bus
Service
Archive Report spam Delete Mark as read
bus.publish('markAsReadRequested', emails);
- 54. © 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 setting up a VPN on firewall
Shopping Carts
The end of textbooks?
3MeMail
Bus
Service
bus.publish('markedAsRead', emails);
Archive Report spam Delete Mark as read
- 55. © 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 setting up a VPN on firewall
Shopping Carts
The end of textbooks?
2MeMail
Archive Report spam Delete Mark as unread
- 56. © 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
- 57. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Which Pattern 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 YesEvent Emitter
Callback Promise
Pub/Sub
- 58. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Patterns Within MV*
§ State Change Detection
§ Declarative Markup
§ View Manipulation
§ Dependency Injection
58
- 59. © 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
- 60. © 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
- 61. © 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
- 62. © 2013 Adobe Systems Incorporated. All Rights Reserved.
MV*
62
Model
Represents data
or state
View
Presentation and
user controls
*
- 63. © 2013 Adobe Systems Incorporated. All Rights Reserved.
MV* Frameworks
63
- 64. © 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 attributes (directives)
Two-way data-binding built-in
Dependency injection built-in
- 65. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Patterns Within MV*
§ State Change detection
§ Declarative Markup
§ View Manipulation
§ Dependency Injection
65
- 66. © 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?
- 67. © 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…
- 68. © 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.
- 69. © 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!)
- 70. © 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'});
- 71. © 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);
- 72. © 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);
- 73. © 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,
http responses, etc.
Can be manually triggered.
TriggerWait
- 74. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Patterns within MV*
§ State Change Detection
§ Declarative Markup
§ View Manipulation
§ Dependency Injection
74
- 75. © 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
- 76. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Templates
var data = {
users: [
{ name: 'John', email: 'john@example.com' },
{ name: 'Jane', email: 'jane@example.com' }
]
};
var source = $('#users-template').html();
var template = Handlebars.compile(source);
var html = template(data);
$('body').html(html);
76
- 77. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Backbone: Templates
<body>
<ul>
<li>Name: John, Email: john@example.com</li>
<li>Name: Jane, Email: jane@example.com</li>
</ul>
</body>
77
- 78. © 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: 'john@example.com'},
{name: 'Jane', email: 'jane@example.com'}
];
}
78
- 79. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Patterns Within MV*
§ State Change Detection
§ Declarative Markup
§ View Manipulation
§ Dependency Injection
79
- 80. © 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
- 81. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Angular: Binding
Name: <input type="text" ng-model="yourName">
<h1>Hello {{yourName}}</h1>
81
- 82. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Patterns within MV*
§ State change detection
§ Declarative Markup
§ View Manipulation
§ Dependency Injection
82
- 83. © 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();
- 84. © 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
TwitterService construction.
- 85. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Inversion of Control Container
When rank is requested, provide the value 1337.
When twitter is requested, provide a new instance of TwitterService.
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
- 86. © 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 $http
and $scope?
- 87. © 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 $http
and $scope?
By using toString() and
some well-crafted regex.
- 88. © 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?
- 89. © 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!
- 90. © 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.
- 91. © 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.
Then we have to annotate.
- 92. © 2013 Adobe Systems Incorporated. All Rights Reserved.
JavaScript Patterns And Principles
§ Modularity
§ Communication Patterns
§ Patterns Within MV*
92
- 93. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Promise Implementations
93
Q
jQuery
rsvp.js
kriskowal/q
jquery/jquery
tildeio/rsvp.js
- 94. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Pub/Sub Implementations
94
Postal.js
AmplifyJS
PubSubJS
postaljs/postal.js
appendto/amplify
mroderick/pubsubjs
- 95. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Inversion of Control and Dependency Injection
95
Article by Martin Fowler
http://martinfowler.com/articles/injection.html
Wikipedia source of truth
http://en.wikipedia.org/wiki/Dependency_injection
Lightweight inversion of control container with examples
https://github.com/Aaronius/injectorjs
- 96. © 2013 Adobe Systems Incorporated. All Rights Reserved.
Inversion of Control and Dependency Injection
96
Article by Martin Fowler
http://martinfowler.com/articles/injection.html
Wikipedia source of truth
http://en.wikipedia.org/wiki/Dependency_injection
Lightweight inversion of control container with examples
https://github.com/Aaronius/injectorjs