An introduction to the different architectures of Ember and Angular, two leading JavaScript singlepage / MVC frameworks.
This presentation was given to the Los Angeles RailsBridge "Architecture" meeting on October 25, 2013.
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Architecture: ember.js and AngularJS
1. Ember.js and AngularJS
Two Architectures Compared
Evan Dorn
and Hannah Howard
Logical Reality Design
http://lrdesign.com
evan@lrdesign.com
@idahoev
hannah@techgirlwonder.com
@techgirlwonder
Tuesday, November 19, 13
2. How do I web application?
Tuesday, November 19, 13
8. BIG APPS NEED
ARCHITECTURE
•Keep
it organized!
•Modularize
your code!
•Separate
concerns!
•Establish
conventions for smooth teamwork!
Tuesday, November 19, 13
9. BIG APPS NEED
ARCHITECTURE
•Keep
it organized!
•Modularize
your code!
•Separate
concerns!
•Establish
conventions for smooth teamwork!
•Keep
Tuesday, November 19, 13
it testable!
10. Most tools use
some variant of
MVC
“Model, View, Controller"
Tuesday, November 19, 13
22. THE PROBLEMS:
•All
•...
possible user actions must be precomputed
and embedded into the HTML
•Reloading
Tuesday, November 19, 13
the whole page every request
23. THE PROBLEMS:
•All
•...
possible user actions must be precomputed
and embedded into the HTML
•Reloading
•Some
the whole page every request
actions not possible without browser
interactivity
Tuesday, November 19, 13
44. PHILOSOPHY: EMBER
•Take
known techniques for building apps
•...
concepts from Rails
•...
concepts from Cocoa
•Apply
Tuesday, November 19, 13
them to the browser
48. PHILOSOPHY: ANGULAR
•Start
from the browser - HTML and CSS
•Extend
those concepts to app creation
•Angular
asks... What would markup look
like, if it were designed for building apps
instead of just pages?
Tuesday, November 19, 13
65. SYN-NAPS #1
•Attentional
focus is best < 15 minutes
•Best
to take breaks to let the synapses
recover
•So
let’s do a little exercise to review
Tuesday, November 19, 13
70. DISCUSS WITH THEM:
1. An app that’s too small to need MVC
2. A small app that grew till it needed MVC
Tuesday, November 19, 13
71. DISCUSS WITH THEM:
1. An app that’s too small to need MVC
2. A small app that grew till it needed MVC
3. Any platform is fine!
Tuesday, November 19, 13
85. EMBER ARCHITECTURE
2: RUNTIME
Ember Watches for
Events
Passes Events To
Controller (or bubbles
up to Route) to update
model
Tuesday, November 19, 13
86. EMBER ARCHITECTURE
2: RUNTIME
Ember Watches for
Events
Passes Events To
Controller (or bubbles
up to Route) to update
model
DOM auto-updates
Tuesday, November 19, 13
90. EMBER ARCHITECTURE
3: ROUTER
•The
entry point for everything in Ember is
the router
•Looks
a lot like a routes.rb in Rails
•Different:
Controller
Tuesday, November 19, 13
Fetches the Model for the
91. EMBER ARCHITECTURE 4: ROUTER
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return ['red', 'yellow', 'blue'];
}
});
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model}}
<li>{{item}}</li>
{{/each}}
</ul>
</script>
Tuesday, November 19, 13
92. EMBER ARCHITECTURE 4: TEMPLATE
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return ['red', 'yellow', 'blue'];
}
});
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model}}
<li>{{item}}</li>
{{/each}}
</ul>
</script>
Tuesday, November 19, 13
103. EMBER ARCHITECTURE 6:
DATA BINDING
•Is
done with computed properties
•Available
on Models, Controllers, Data
Stores, etc.
Tuesday, November 19, 13
104. EMBER ARCHITECTURE 6:
DATA BINDING
•Is
done with computed properties
•Available
on Models, Controllers, Data
Stores, etc.
•Define
a function property and add
dependencies to it with .properties()
Tuesday, November 19, 13
105. EMBER ARCHITECTURE 6: DATA BINDING
App.Ticket = Ember.Object.extend({
name: null,
priority: null,
abbreviation: function () {
shortName = this.get('name');
return shortName.slice(0,3);
}.property('name')
});
Tuesday, November 19, 13
106. EMBER ARCHITECTURE 6: DATA BINDING
App.Ticket = Ember.Object.extend({
name: null,
priority: null,
abbreviation: function () {
shortName = this.get('name');
return shortName.slice(0,3);
}.property('name')
});
Tuesday, November 19, 13
111. ANGULAR ARCHITECTURE
1: STARTUP
Angular reads a
marked-up HTML file
Processes it according
to directives (yours
and AJS’s)
Binds view elements to
Model data
Tuesday, November 19, 13
114. ANGULAR ARCHITECTURE
2: RUNTIME
Angular watches for
events, and changes
to bound entities
Updates bound pairs,
calls watch methods
Tuesday, November 19, 13
115. ANGULAR ARCHITECTURE
2: RUNTIME
Angular watches for
events, and changes
to bound entities
Updates bound pairs,
calls watch methods
Re-renders the DOM
as a result
Tuesday, November 19, 13
117. ANGULAR ARCHITECTURE
3: $SCOPE
•A special JS object that groups all the stuff for the
current controller context.
Tuesday, November 19, 13
118. ANGULAR ARCHITECTURE
3: $SCOPE
•A special JS object that groups all the stuff for the
current controller context.
•Has inheritable properties and sub-scopes; a bit
magical
Tuesday, November 19, 13
119. ANGULAR ARCHITECTURE
3: $SCOPE
•A special JS object that groups all the stuff for the
current controller context.
•Has inheritable properties and sub-scopes; a bit
magical
•Inheritance is determined by controller
inheritance.
Tuesday, November 19, 13
122. ANGULAR ARCHITECTURE
4:MODELS
•A model is any JS object (not function!) assigned
as a property on the current $scope.
•No class to extend!
Tuesday, November 19, 13
123. ANGULAR ARCHITECTURE
4:MODELS
•A model is any JS object (not function!) assigned
as a property on the current $scope.
•No class to extend!
•Automatically available to any controller that uses
that $scope or a sub-scope.
Tuesday, November 19, 13
124. ANGULAR ARCHITECTURE
4:MODELS
•A model is any JS object (not function!) assigned
as a property on the current $scope.
•No class to extend!
•Automatically available to any controller that uses
that $scope or a sub-scope.
•Automatically two-way bound to view elements
Tuesday, November 19, 13
127. ANGULAR ARCHITECTURE
5: CONTROLLERS
•A controller is just any JS function that receives
and processes on a $scope.
•No class to extend or API to call!
Tuesday, November 19, 13
128. ANGULAR ARCHITECTURE
5: CONTROLLERS
•A controller is just any JS function that receives
and processes on a $scope.
•No class to extend or API to call!
•Which controller is relevant is determined by the
markup.
Tuesday, November 19, 13
129. ANGULAR ARCHITECTURE
5: CONTROLLERS
•A controller is just any JS function that receives
and processes on a $scope.
•No class to extend or API to call!
•Which controller is relevant is determined by the
markup.
•Inheritance is determined by the markup, too!
Tuesday, November 19, 13
130. ANGULAR ARCHITECTURE 5: CONTROLLERS
<div ng-controller="SomeController">
{{name}} is {{comment}}!
<div ng-controller="InnerController">
{{name}} is {{comment}}!
</div>
</div>
function SomeController($scope, []) {
$scope.name = “Evan”
$scope.comment = “really cool”
}
function InnerController($scope, []) {
$scope.comment = “misinformed”
}
#output
Evan is really cool
Evan is misinformed
Tuesday, November 19, 13
131. ANGULAR ARCHITECTURE 5: CONTROLLERS
<div ng-controller="SomeController">
{{name}} is {{comment}}!
<div ng-controller="InnerController">
{{name}} is {{comment}}!
</div>
</div>
function SomeController($scope, []) {
$scope.name = “Evan”
$scope.comment = “really cool”
}
function InnerController($scope, []) {
$scope.comment = “misinformed”
}
#output
Evan is really cool
Evan is misinformed
Tuesday, November 19, 13
132. ANGULAR ARCHITECTURE 5: CONTROLLERS
<div ng-controller="SomeController">
{{name}} is {{comment}}!
<div ng-controller="InnerController">
{{name}} is {{comment}}!
</div>
</div>
function SomeController($scope, []) {
$scope.name = “Evan”
$scope.comment = “really cool”
}
function InnerController($scope, []) {
$scope.comment = “misinformed”
}
#output
Evan is really cool!
Evan is misinformed!
Tuesday, November 19, 13
134. ANGULAR ARCHITECTURE
6: DATA BINDING
•Bound DOM elements and model data autoupdate each other.
Tuesday, November 19, 13
135. ANGULAR ARCHITECTURE
6: DATA BINDING
•Bound DOM elements and model data autoupdate each other.
•Other code like controller functions that depend
on model data are not auto-updated.
Tuesday, November 19, 13
136. ANGULAR ARCHITECTURE
6: DATA BINDING
•Bound DOM elements and model data autoupdate each other.
•Other code like controller functions that depend
on model data are not auto-updated.
•but $scope.$watch can create such bindings
Tuesday, November 19, 13
137. ANGULAR ARCHITECTURE 6: DATA BINDING
<div ng-controller="SomeController">
<input type=‘text’ ng-model=‘name’></input>
You typed {{name}}!
</div>
function SomeController($scope, []) {
# name isn’t even mentioned!
# in fact you don’t even need the controller!
}
Tuesday, November 19, 13
138. ANGULAR ARCHITECTURE 6: DATA BINDING
<div ng-controller="SomeController">
<input type=‘text’ ng-model=‘name’></input>
You typed {{name}}!
</div>
function SomeController($scope, []) {
# name isn’t even mentioned!
# in fact you don’t even need the controller!
}
Tuesday, November 19, 13
139. ANGULAR ARCHITECTURE 6: DATA BINDING
<div ng-controller="SomeController">
<input type='text' ng-model='name'></input>
{{crazy_string}}
</div>
function SomeController($scope, []) {
$scope.crazy_string = $scope.name + " is crazy!";
}
Tuesday, November 19, 13
140. ANGULAR ARCHITECTURE 6: DATA BINDING
<div ng-controller="SomeController">
<input type='text' ng-model='name'></input>
{{crazy_string}}
</div>
function SomeController($scope, []) {
$scope.crazy_string = $scope.name + " is crazy!";
}
Tuesday, November 19, 13
141. ANGULAR ARCHITECTURE 6: DATA BINDING
<div ng-controller="SomeController">
<input type='text' ng-model='name'></input>
{{crazy_string}}
</div>
function SomeController($scope, []) {
$scope.crazy_string = $scope.name + " is crazy!";
}
Tuesday, November 19, 13
142. ANGULAR ARCHITECTURE 6: DATA BINDING
<div ng-controller="SomeController">
<input type='text' ng-model='name'></input>
{{crazy_string}}
</div>
function SomeController($scope) {
$scope.$watch('name', function(){
$scope.crazy_string = $scope.name + " is crazy!";
})
}
Tuesday, November 19, 13
143. ANGULAR ARCHITECTURE 6: DATA BINDING
<div ng-controller="SomeController">
<input type='text' ng-model='name'></input>
{{crazy_string}}
</div>
function SomeController($scope) {
$scope.$watch('name', function(){
$scope.crazy_string = $scope.name + " is crazy!";
})
}
Tuesday, November 19, 13
144. ANGULAR ARCHITECTURE 6: DATA BINDING
<div ng-controller="SomeController">
<input type='text' ng-model='name'></input>
{{crazy_string}}
</div>
function SomeController($scope) {
$scope.$watch('name', function(){
$scope.crazy_string = $scope.name + " is crazy!";
})
}
Tuesday, November 19, 13
146. ANGULAR ARCHITECTURE
7: DEPENDENCY INJECTION
•All elements get created created with a name (as
a string) they are known by.
Tuesday, November 19, 13
147. ANGULAR ARCHITECTURE
7: DEPENDENCY INJECTION
•All elements get created created with a name (as
a string) they are known by.
•Controllers, services, etc.
Tuesday, November 19, 13
148. ANGULAR ARCHITECTURE
7: DEPENDENCY INJECTION
•All elements get created created with a name (as
a string) they are known by.
•Controllers, services, etc.
•All elements get instantiated with a list of names
they depend on.
Tuesday, November 19, 13
149. ANGULAR ARCHITECTURE
7: DEPENDENCY INJECTION
•All elements get created created with a name (as
a string) they are known by.
•Controllers, services, etc.
•All elements get instantiated with a list of names
they depend on.
•This makes test isolation trivial
Tuesday, November 19, 13
150. ANGULAR ARCHITECTURE 7: DI
var ticketApp = angular.module('ticketApp', []);
ticketApp.factory('TicketList', function(){ # ... });
ticketApp.service(‘BackEndAjaxProvider’, function() { #... })
function TicketsController($scope, TicketList) { #... };
function TicketEditController($scope, [TicketList,
BackEndAjaxProvider]) { #... };
Tuesday, November 19, 13
151. ANGULAR ARCHITECTURE 7: DI
var ticketApp = angular.module('ticketApp', []);
ticketApp.factory('TicketList', function(){ # ... });
ticketApp.service('BackEndAjaxProvider', function() { #... })
function TicketsController($scope, TicketList) { #... };
function TicketEditController($scope, [TicketList,
BackEndAjaxProvider]) { #... };
Tuesday, November 19, 13
152. ANGULAR ARCHITECTURE 7: DI
var ticketApp = angular.module('ticketApp', []);
ticketApp.factory('TicketList', function(){ # ... });
ticketApp.service(‘BackEndAjaxProvider’, function() { #... })
function TicketsController($scope, TicketList) { #... };
function TicketEditController($scope, TicketList,
BackEndAjaxProvider) { #... };
Tuesday, November 19, 13