JavaScript Patterns and Principles

Post on 17-May-2015

4508 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

Transcript

© 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: '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

© 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

© 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

© 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

top related