SlideShare a Scribd company logo
FROM SCRATCH!
github.com/xmlilley/ng-demos
@ Angular Meetup DC, 11/13/13

by: Christian Lilley
about.me/XML
Friday, November 15, 13

@XMLilley
GOALS & ASSUMPTIONS
• We’re

all familiar with basic Javascript & HTML & MVC
terminology, but maybe not Angular’s take on it.

• Yeoman

is awesome. But the Yeoman way and the basic
(naïve) way aren’t really compatible in a 2-hr session. We’ll
leave Yeoman for another day.

•I

wish there was more time for audience hands-on tonight, but
Angular’s a big topic. So, all the demo code is available for
take-home experimentation.

• Save

questions for breaks & the end, pls. I’ll stick around.

Friday, November 15, 13
ANGULAR BUZZWORDS
Full Application Framework,
not a Library
• MV*
• Convenient Abstractions
• Total Modularity, Reusability
• Pub-Sub Communications
Between Modules
• Dependency Injection
• Routing, Deep-Linking, History
• Filters, Expression Interpolation
•

Friday, November 15, 13

Data-Binding
• HTML Templating
• Testing Baked-In (Karma)
• Integrated Promises ($Q)
• Localization
• Form Validation
• “Big UI”
• MIT License
•
ANGULAR IS ALL ABOUT...
• MV*: A

data model, templates for viewing/interacting with it,
and logic in controllers, services, directives, etc.

• Declarative

Behavior: Protect Extend HTML. HTML is
right for templates, not JS. Intentions are visible in templates.

• Data-Binding: User

or Program can modify the model, and
views update automagically to reflect those changes.

• Model-Driven

Behavior: DOM / View updates based on
model, not brittle imperative logic. Truth in DOM Model.

• Modular

Architecture, Separated Concerns: DOM
changes in Directives, model changes in Controllers, abstracted
app-wide support functions & data in Services

Friday, November 15, 13
Let’s get started!

Friday, November 15, 13
Friday, November 15, 13
Bootstrapping
Your App
The ng-app directive tells Angular
what part of your main template it
needs to watch. It ‘wakes up’
Angular.
You can (should) define a specific
Angular module to serve as the core
app logic: ng-app=‘myModule’
You can also bootstrap manually, if
you need to.
Friday, November 15, 13
Data-Binding
Angular’s declarative 2-way databinding is part of its special sauce.
Changing data
automagically
Changing data
automagically

in the model
updates the view.
in the view
updates the model.

model -> view -> model -> view
LET ANGULAR DO THIS FOR YOU! It’s
part of Angular’s emphasis on
model-driven UI.
Friday, November 15, 13
DOM

Then
shows final
outcome in
the DOM

Angular
watches for
changes
here

Don’t do
imperative DOM
Changes!

Consequent
model changes
by Angular

MODEL
Model
Changes can
start
anywhere

Friday, November 15, 13

Updates the
model
accordingly

Truth
lives Here!
Not in DOM!
Tells Angular: “Watch this space”

Tells Angular: “Bind this input.”
Tells Angular: “Insert Data here.”
Friday, November 15, 13
But what about those
curly-brackets?

ANGULAR EXPRESSIONS
Friday, November 15, 13
With an Angular
Expression, You Can:
Do math, or comparison
Concatenate text
Reference a model property
Invoke a function
But not: Control Flow, like
conditions or loops
(app logic belongs in controllers)
Friday, November 15, 13
One more thing you
can do:
Filter the output of the expression
Filters are applied by ‘piping’ an
expression into one:
{{modelName.propertyName	
  |	
  filterName:arg}}

Friday, November 15, 13
DEMO DEMO DEMO

Friday, November 15, 13
So, How Can we Build
a More Complicated
App Than This?
Organize code with
MODULES
Friday, November 15, 13
Modules are where we put our code:
like filters, controllers,
directives, services, and
configuration information.
They provide us with encapsulation
and re-usability for macro-level
groupings of code.
Note that
angular.module(‘moduleName’) is both
a creator and a retriever.
Friday, November 15, 13
And when we want to
organize our data
(view-models), too?
Organize view data
& functions with
CONTROLLERS
Friday, November 15, 13
Controllers Intro
Controllers are function Instances, used
for interacting w/ data in views:
They’re created and destroyed along
with elements/templates.
multiple invocations = multiple
instances
If you want persistence, either place
on an element that’s persistent, or
place the data/methods in a service
(more later).
Hard to address a *specific*
controller, so use events for
communication (more later).
Friday, November 15, 13
DEMO DEMO DEMO

Friday, November 15, 13
Services Intro
Services are ludicrously simple:
Remember (from, like, 1 slide ago),
how controllers are created and
destroyed every time you need one?
And there can be lots of instances of
a single controller type?
Services, by contrast, are unicorns,
and last forever.
(jargon: ‘lazy-loaded singletons’)

Friday, November 15, 13
Templates/Views Intro
In Angular, HTML is the template
language!
Use inline HTML, external files, or
simple strings as templates.
Then use expressions (and directives)
to insert data from your model into
the view.
Re-use templates with different
controllers, re-use controllers with
different templates.
Friday, November 15, 13
DEMO DEMO DEMO

Friday, November 15, 13
Routing Intro
Since we’re extending HTML in our
templates, let’s extend the browser
too.
Routing lets you drive your interface
views using the content of the
location/URL bar.
This lets our Angular Apps behave
just like the server-side apps that
users are used to, with forward/back
and deep-linking to specific content.

Friday, November 15, 13
DEMO DEMO DEMO

Friday, November 15, 13
Directives Intro
Controllers are just for data
interactions. So DOM code has to go
somewhere. Directives it is.
Modular, re-usable, de-coupled DOM
logic. Directives embody all of
Angular’s major design principles.
Way easier to use than the (old)
Angular docs make it seem. We’ll have
you writing your own in no time.

Friday, November 15, 13
Directive Pop-Star:
NG-REPEAT
Everybody digs it: throw a series of
data into your view super-easily.
Like ‘collection-views’ in other
libraries
filter/sort the output if you like

Friday, November 15, 13
DEMO DEMO DEMO

Friday, November 15, 13
Coming up...
the DEETS
First... Questions?

Friday, November 15, 13
CONTROLLERS
In (a smidge more) Detail

Friday, November 15, 13
About Controllers
Best-practice: use controller only
for dealing with data/model. Let
directives handle updating the views
based on the properties of the model.
Two ways to define:
using .controller() method on a
module
As an ordinary named function
(This will wind up on global
scope. No good reason to do this.
Just recognize it if you see it.)
Friday, November 15, 13
TEMPLATES/VIEWS
In Detail

Friday, November 15, 13
Templates Demo
Note: when we provide the name of a
template in the declaration of a
directive like ng-include, we have to
wrap it in a second pair of quotes.
The first pair of quotes delimits an
expression, which will be eval()’d by
Angular. Since we supply a template
path as a string, it needs the
quotes. We could also reference a
property on the model, without
needing to do that.
Friday, November 15, 13
Templates/Views
We can include templates
conditionally, using directives like
ng-show/ng-hide, ng-if, ng-switch
(We’ll also demonstrate how to use
custom directives as another way to
include a template.)
But the most powerful way to
conditionally show content, is to use
the browser’s address bar. Which
means we want...

Friday, November 15, 13
Templates SNAFU
Browsers don’t like to let you access
external local files. This sets off ‘sameorigin’ errors. Simple solution: start a
server. Painless Javascript/Node approach:

>>	
  sudo	
  npm	
  install	
  -­‐g	
  http-­‐server
>>	
  http-­‐server	
  (or:	
  `node	
  bin/http-­‐server`)
But, no logging!
‘Ole-reliable Python option with logging:

>>	
  python	
  -­‐m	
  SimpleHTTPServer	
  8000
Or, the faster ‘Twisted’ (comes w/ OSX):

>>	
  twistd	
  -­‐no	
  web	
  -­‐-­‐path=.
Friday, November 15, 13
Templates SNAFU
Or, you can just use Yeoman/Grunt:
>>	
  grunt	
  server
(do this)

Friday, November 15, 13
ROUTING
In Detail

Friday, November 15, 13
First: $location
Angular’s $location service is bound
to window.location (ie. to what’s in
the browser’s ‘address bar’)
Changes to the URL in the address bar
are reflected in $location & changes
to $location are reflected in address
bar.
‘Back’ & ‘Forward’ are supported, as
is deep-linking
See: “Using $location” guide
Friday, November 15, 13
$route
The $route service (configured via
$routeProvider) gives us the ability
to react programmatically to changes
in the $location (plus $routeParams).
We specify a template that will be
rendered inside an <ng-view> in
response to a given route-change,
along with its controller and some
other details.

Friday, November 15, 13
Routing Is A Config
For Your App Module
Fundamentally, routing works as a
configuration detail on your base
application module. (The one in ng-app.)
There are two ways to configure your
app: by supplying a config function at
module creation, or by invoking the
config function on your app after
creation...

Friday, November 15, 13
2 Ways to Config App
A config function is the (unpopular)
third argument to a module’s creation:
myModule = angular.module(name, [dependencies],
function(injectables) {
// Configuration details, like routing
});

Or, after the fact w/ Module.config( )
myModule.config(function(injectables) {
// Configuration details, like routing
});

Friday, November 15, 13
Routing Syntax
Routes are added via configuration
methods called on $routeProvider in
the app config function.
There are only two basic methods
involved:
$routeProvider.when(path, route)
$routeProvider.otherwise(params)

Friday, November 15, 13
Route Config Object
We can include an optional route config
object for each path, with the following
options:
template: html template as string
templateUrl: path to a partial
controller: binds an instance of
specified controller to the template
instance
redirectTo: a path string or a function
that returns one
resolve: a function or service reference
that will execute (or promise that
resolves) before $routeChangeSuccess

Friday, November 15, 13
Routing Example
myModule.config(function($routeProvider) {
$routeProvider
.when('/home', { templateUrl: 'home.html',
controller: homeCtrl })
.when('/index', { redirectTo: '/home’ })
.when('/archive/doc/:docId',
{ templateUrl: 'archive_doc.html',
controller: archCtrl })
.when('/contact', { templateUrl: 'poc.html',
controller: pocCtrl,
resolve: {
// I will cause a 1 second delay
delay: function($q, $timeout) {
var delay = $q.defer();
$timeout(delay.resolve, 1000);
return delay.promise; }})
.otherwise({ redirectTo: '/home' });
});
Friday, November 15, 13
.otherwise()
The only property in the .otherwise()
config object is redirectTo
NOTE: the value of redirectTo should be a
path, like ‘/home’, not a template location
like ‘home.html’. The route for ‘/home’
will then take care of supplying the
template.
myModule.config(function($routeProvider) {
$routeProvider
.when('/home', { templateUrl: 'home.html',
controller: homeCtrl })
.otherwise({ redirectTo: '/home' });
});
Friday, November 15, 13
Named Groups in Path
The path can contain ‘named groups’
starting with a colon (/path/path/:name).
All characters between colon and next
slash are matched and stored in
$routeParams.
From $routeParams, you can access that
data and use it in preparing the view,
based on related data.
Good technique for dynamically including
data from a collection: users, products,
chapters, etc.
Friday, November 15, 13
Named Groups in Path
example definition from Angular docs:
$routeProvider.when('/Book/:bookId/ch/:chapterId',
{templateUrl: 'chapter.html',
controller: ChapterCntl
});

Example URL:

//docs.angular.org/Book/Gatsby/ch/4
The Route Params you’ll see for that:
$routeParams = {"bookId":"Moby","chapterId":"1"}

Friday, November 15, 13
$scope & Models
In Detail

Friday, November 15, 13
‘Models’
Unlike Ember, Angular doesn’t force
you into creating OOP models using
their abstractions. Do as you like.
But model data should reside in
objects that are properties on the
$scope (‘model objects’, if you
will), not directly in properties of
the scope. Operations upon properties
stored directly on $scope can have
unexpected results. This is *totally*
undocumented, but comes from Angular
core team.
Friday, November 15, 13
WTF is $scope ???
So, if Angular models are just plainold Javascript objects (POJOs), what
do we need this $scope thing for?
Dependency Injection
Angular will
the correct,
you need it:
controllers,

use DI to make sure that
contextual data is where
in re-usable
directives & views.

$scope also gives us inheritance, via
a DOM-like tree. Data available to
app root is also available on leaves.
Friday, November 15, 13
$rootScope

Main/Nav
Controller
$scope
View 1
Controller
$scope

Directive A-1
$scope

Friday, November 15, 13

Directive B
$scope

Directive C can
access all
properties from
all three parent
scopes

View 2
Controller
$scope

Directive A-2
$scope

Directive C
$scope
Visualizing Scope
Use the Angular Batarang!!!

Friday, November 15, 13
SERVICES
In Detail

Friday, November 15, 13
Services in Detail:
Why Services?
Provide re-usable, testable modular
utilities across the application
Abstract implementation details, and
simply provide a convenient API to
other parts of the application.
Provide persistent application state
across controller, view & directive
*instances*
Friday, November 15, 13
Services in Detail
‘Back-office’ functions, like
networking, event-dispatch, etc.
Lazy-loaded singleton modules that
persist through the life-cycle of the
app, once instantiated.
Injected dependencies that can be
used by any other module
Examples: $http, $log, $location,
$route, & services used only by
Angular: $provide, $injector, $parse
Friday, November 15, 13
Services: A Metaphor
In some ways, an Angular Service is
little more than a stateful,
application-wide controller.

Friday, November 15, 13
How are custom Services
different from built-ins?
They’re not.
At all.
No, really.
(Well, OK: they’re different in
naming conventions: don’t use ‘$’ in
your custom services.)
Friday, November 15, 13
Defining Services
There are wayyy too many patterns for
defining a service, and the Angular
docs fail to even mention the simplest,
most intuitive one, using the
module’s .service() convenience method
(which also aliases to .factory):

var app = angular.module('appModule',
['dependency1']);
app.service(‘serviceName’, function() {
return shinyNewServiceInstance;
});
Friday, November 15, 13
Defining Services
The older version of service creation,
which you’ll still find in the docs,
involves the module’s config function
and calling .factory (or .service) on
$provide:
angular.module('appModule',[‘dependency1’])
.config(function($provide) {
$provide.factory('serviceName', function() {
return shinyNewServiceInstance;
});
});

Friday, November 15, 13
So, how crazy
complicated is the
service instance
itself?

Friday, November 15, 13
shinyNewServiceInstance
Relax! Here, we get to rely on
standard JS pragmatics:
return either a single
function or a revealed module,
as you wish
allows public & private
properties in the constructor

Friday, November 15, 13
Single-Function Service
angular.module('appModule', [], function($provide) {
$provide.factory('notifySvc', function() {
var msgs = []; //private variable
return function(msg) { //public function
msgs.push(msg);
if (msgs.length == 3) {
alert(msgs.join("n"));
msgs = [];
}
};
});

Just call with notifySvc(msg), after
injecting into a controller or directive
Friday, November 15, 13
Multi-Property Service
angular.module('appModule', [])
.service('notifySvc', function() {
var msgs = []; //private variable
return {
submit: function(msg) { msgs.push(msg); },
dump: function() {
if (msgs.length == 3) {
win.alert(msgs.join("n"));
msgs = [];
}
};
}});

Just call with notifySvc.submit(msg) and
notifySvc.dump()
Friday, November 15, 13
Service Instantiation
Remember: Services are ‘lazy-loaded
singletons’. That means the service
instance won’t actually be created
until you specifically need it.
You tell Angular you need it by
injecting it into a controller,
directive, etc.

Friday, November 15, 13
Referencing Services
In a directive or controller, you can
have direct access to a service and
its properties, assuming you have
injected it properly.
In HTML (an interpolated expression),
you can’t reference until you’ve
attached it to local $scope. So, in
your controller:
$scope.property = serviceName.serviceProperty;

Friday, November 15, 13
DIRECTIVES
In Detail

Friday, November 15, 13
What are
Directives, Again?

Friday, November 15, 13
Friday, November 15, 13
What Are They, Really?
5(-ish) words:
Logic & Behavior For UI
“...a way to teach HTML new tricks.”
Anything in your app that touches DOM
Examples: event-handling, behavior
management, template pre-processing &
insertion, data-binding, ‘Collection
Views’, UI Widgets, conditional
display, i18n & localization, etc.
Friday, November 15, 13
What Are They, Really?
The only other Angular construct that
really touches the DOM is:
Angular Expressions (text only).
Filters
The rest of it should be in
Directives. (Even the ng-view that
executes your routing is simply a
model-driven directive...)

Friday, November 15, 13
What Are They, Really?
Structurally speaking, a Directive is
just a function that’s attached to an
element.
But not just a function: a whole
execution environment. Really,
Directives are mini-applications.
You can think of them as little
robotic pilots that live on your DOM
elements & tell them what to do.

Friday, November 15, 13
Friday, November 15, 13
What AREN’T they?
Directives.
Aren’t.

Goes!

Just.

Please,

Where.

God:

Your.
Friday, November 15, 13

JQuery.

No.
I

BUT...
Friday, November 15, 13
Angular isn’t just
another way to
organize the same
old UI code!!!

Friday, November 15, 13
Opinionated
Principles
1.Declarative, Model-Driven Behavior

Friday, November 15, 13
Why Declarative?
IMPERATIVE = YOUR PROBLEM
DECLARATIVE = SOMEBODY ELSE’S PROBLEM
Easier To Read, Maintain: Why scatter
event-listeners across 100 linked JS
files, then need to go search for
them to find out what’s happening on
an element.

Friday, November 15, 13
Declarativeness ROCKS
You’re trying to find handlers for
this element:

<button id=”1” class=”B C”></button>
Well, where are the event-handlers?
On ‘#1’? On ‘.B’? ‘.C’? On ‘button’?
What if it’s on ‘parentDiv>:firstchild’?
You can’t misunderstand what’s
happening with declarative directives:

<button md-action-handler></button>
Friday, November 15, 13
Extending HTML...
HTML is NOT a virgin bride or
hothouse flower.
The Semantics Wars are over. HTML is
a highly-abstracted, Object-Oriented
language for app interfaces and for
*presenting* documents. Docs
themselves are increasingly stored in
other formats, like markdown.
We’re not abandoning accessibility.
But it’s not a binary choice, anyway.
Friday, November 15, 13
Opinionated
Principles
1.Declarative, Model-Driven Behavior
2.Modularity, Reusability across
contexts: Write Once, Run Anywhere

Friday, November 15, 13
Reusability
It’s all about context-awareness,
data-binding & DI.
Directives know their own element and
local scope.
You can pass additional data into
directives as attributes, right on
the element.

Friday, November 15, 13
<div id="header_tabs">
<a href="#/home" active-tab="1">HOME</a>
<a href="#/finance" active-tab="1">Finance</a>
<a href="#/hr" active-tab="1">Human Resources</a>
<a href="#/quarterly" active-tab="1">Quarterly</a>
</div>

AND...
<div id="subnav_tabs">
<a href="#/hr/pay" active-tab="2">Pay</a>
<a href="#/hr/benefits" active-tab="2">Benefits</a>
<a href="#/hr/help" active-tab="2">Help</a>
</div>

Friday, November 15, 13
Opinionated
Principles
1.Declarative, Model-Driven Behavior
2.Modularity, Reusability across
contexts: Write Once, Run Anywhere
3.Keep it Local

Friday, November 15, 13
No...

Friday, November 15, 13
Yes: ‘Local’
Sticks to a self-contained, modular
scope, which understands its context:
inside the directive, `element` is
like `this`.
Uses messages, models to affect
things elsewhere.
Easier to maintain, easier to read,
easier to scale.
But the challenge to all that is:
Friday, November 15, 13
My Awesome Website
Needs to
Change
Things Here
Sweet Product

Cart: 1 Item(s)

$899.99

Buy Now!

Product Description: Lorem ipsum
dolor sit amet, consectetur
adipiscing elit. In erat mauris,
faucibus quis pharetra sit amet,
pretium ac libero. Etiam vehicula
eleifend bibendum. Morbi gravida
metus ut sapien condimentum sodales
mollis augue sodales. Vestibulum
quis quam at sem placerat aliquet.
Curabitur a felis at sapien
ullamcorper fermentum. Mauris
molestie arcu et lectus iaculis sit
amet eleifend eros posuere. Fusce
nec porta orci.

Clicking Here

Friday, November 15, 13

Integer vitae neque odio, a
sollicitudin lorem. Aenean orci
mauris, tristique luctus fermentum
eu, feugiat vel massa. Fusce sem
Let’s Build Some!
but first...
Questions?

Friday, November 15, 13
Directive Names
Angular uses a convention borrowed
from other JS projects: names in HTML
are hyphenated...

<sample-directive></sample-directive>
while identifiers in the JS are
camel-cased:
.directive(‘sampleDirective’, function(){})
Expect Angular to do this conversion
automatically. Don’t fight it.
Friday, November 15, 13
How are custom directives
different from built-in?
They’re not.
At all.
No, really.
(Well, OK: they’re different in
naming conventions: don’t use ‘ng-’
in your custom directives.)
Friday, November 15, 13
CREATION
.directive() is a method we call on
an angular.module(), either at
creation time or via reference,
passing a name and a factory function
angular
.module('moduleName', ['dependency1', 'dependency2'])
.directive('directiveName', factoryFunction() {})

The factory will return either a
function or an object containing a
function and other settings

Friday, November 15, 13
Factories
(Note, when we talk about generic
‘factories’, we don’t mean $factory,
which is an Angular implementation
service.)
The factory pattern is all about
Functional Programming: using basic
Javascript functions to build and
return either naiive objects or other
functions.

Friday, November 15, 13
What do We Do With
The Factory
Function?

Friday, November 15, 13
Two Basic Options:
Return a
Config Object or a
‘Linking Function’

Friday, November 15, 13
Friday, November 15, 13
Friday, November 15, 13
You’ll See Later, But
Ignore For Today:
Returning only the Link
function
Link vs. Compile
Pre-Link vs. Post-Link
Friday, November 15, 13
Friday, November 15, 13
Using a Config Object
angular.module('moduleName').
directive('sampleDirective', function(){
	 return {
link: function(scope, element, attrs) {
	 	
// this example binds a behavior to the
// mouseenter event
element.bind("mouseenter", function(){
	 	 	 	 ... do stuff after mouseenter ...
	 	
}
},
restrict: ‘E’,
template: “<div>Hello, World!</div>”
	 }})

Everything but `link` is optional.
Friday, November 15, 13
Link Function Args
.directive('sampleDirective', function(){
	 return {
link: function(scope, element, attrs) {
	 	
// this example binds a behavior to the
// mouseenter event
element.bind("mouseenter", function(){
	 	 	 	 ... do stuff after mouseenter ...
	 	
}
},
restrict: ‘E’,
template: <div>Hello, World!</div>
	 }
})

Friday, November 15, 13
Link Function Args
3 standard params for a link function.
(Plus optional 4th: controller.) They’re
supplied as args by the directive function,
if specified.
scope: whatever scope object is local
element: element declared on: `this`
attrs: an object containing the html
attributes defined on the element,
including the directive invocation itself
Supplied to the function not by name but in
order. Call them whatever you want.
Friday, November 15, 13
jqLite:
your path to the DOM
Angular will defer to JQuery, if
present, but provides its own subset
of JQuery for basic DOM tasks.
You can’t just use $(), nor find
using selectors, unfortunately.
But all built-in `element` refs are
already pre-wrapped in jqlite object
Chain methods as you normally would
Friday, November 15, 13
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•

addClass()
after()
append()
attr()
bind()
children()
clone()
contents()
css()
data()
eq()
find()
hasClass()
html()
next()
on()

Friday, November 15, 13

•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•

off()
parent()
prepend()
prop()
ready()
remove()
removeAttr()
removeClass()
removeData()
replaceWith()
text()
toggleClass()
triggerHandler()
unbind()
val()
wrap()
Using jqLite

(angular.element)

.directive('sampleDirective', function(){
	 return {
link: function(scope, element, attrs) {
	 	
// this example binds a behavior to the
// mouseenter event
element.bind("mouseenter", function(){
	 	 	 	 ... do stuff after mouseenter ...
	 	
}
},
restrict: ‘E’,
template: <div>Hello, World!</div>
	 }})

$(‘selector’).bind(‘mouseenter’, function() {})
Friday, November 15, 13
ACK! THPPPT!!
.bind() is ancient!
Where’s .live() ?!?
.on() ?!?
Friday, November 15, 13
Friday, November 15, 13
A Thought:
If angular.element() / jqlite doesn’t
support what you’re trying to do...
ask yourself: why not?
Because they’re lazy bastards?
Not so much. Think about other options.
Go with the grain, and Angular will
reward you.

Friday, November 15, 13
Directive Templates
Templates can be stored as strings on
the `template:` property
They can also be loaded from a file,
using:
`templateUrl: path/to/file/template.html’

Friday, November 15, 13
Templates
.directive('sampleDirective', function(){
	 return {
link: function(scope, element, attrs) {
	 	
// this example binds a behavior to the
// mouseenter event
element.bind("mouseenter", function(){
	 	 	 	 ... do stuff after mouseenter ...
	 	
}
},
restrict: ‘E’,

template: ‘<div>Hello, World!</div>’
//or:

templateUrl: ‘path/to/file.html’
})
Friday, November 15, 13
The Restrict Property
.directive('sampleDirective', function(){
	 return {
link: function(scope, element, attrs) {
	 	
// this example binds a behavior to the
// mouseenter event
element.bind("mouseenter", function(){
	 	 	 	 ... do stuff after mouseenter ...
	 	
}
},

restrict: ‘E’,
template: <div>Hello, World!</div>
	 }
})

Friday, November 15, 13
The Restrict Property
Remember that directives are re-usable
So, we can restrict the usage of a
directive to (a) specific context(s), so
that we don’t accidentally try to use it
in a situation it wasn’t designed for:
‘E’ = Element
‘A’ = Attribute
‘C’ = Class
‘M’ = Comment
Stack as a single string: ‘EACM’.
Defaults to ‘A’.
Friday, November 15, 13
The Replace Property
By default, a directive element will
wrap the contents of a template. The
`element` object will be the outer
directive element.
To instead replace the directive
element (and object) with the contents
of the template, use {replace: true}
This is esp critical when declaring as
an element...
Friday, November 15, 13
Directives
DEMO BREAKDOWN 1:
Enter-Leave

Friday, November 15, 13
So, about that:
Model-Driven & Local
Directive Design...

Friday, November 15, 13
Specifically, the
Model-Driven
part...

Friday, November 15, 13
Why Model-Driven?
After all, the imperative
approach works fine...
...if you’re omniscient
and precognitive.
... and you really, really
like refactoring.
Friday, November 15, 13
How Can Directives
React to Models?

With $watch!

Friday, November 15, 13
Directives
DEMO BREAKDOWN 2:
CLOCK
(haha! Get it? We’re going to use
a clock to demo $watch...)
Friday, November 15, 13
Keeping Directive
Design Local

Friday, November 15, 13
How Can Directives
React to Stuff that
Happens Far, Far Away?
Again, with models & $watch!
But sometimes, the inheritance
chain isn’t a good solution. For
those times...
Angular events!

$on(), $emit(), $broadcast()
Friday, November 15, 13
Advanced Topic:
Inter-Scope Communication
Use $watch to monitor properties of
local $scope or one it inherits from
That works great when you only need
data to flow in one direction (up)
and only on one branch of the tree.
What about when you need to go
downwards, or sideways?
Or a whole bunch of places at once?
Friday, November 15, 13
$rootScope

???

Main/Nav
Controller
$scope ???

View 1
Controller
$scope

???
???

View 2
Controller
$scope

???
Directive A-1
$scope

Friday, November 15, 13

Directive B
$scope

Directive A-2
$scope

Directive C
$scope
Angular Events to
The Rescue!!!
Just like how a ‘click’ event bubbles
up through the DOM tree, you can
$emit() an Angular event up the
$scope tree, from any starting point.
Better than the DOM, you can also
$broadcast() an event down the $scope
tree.
$broadcast()-ing from $rootScope gets
you the whole shebang.
Friday, November 15, 13
Friday, November 15, 13
Angular Events to
The Rescue!!!
With events, there’s no need to
laboriously climb your way up the
$scope tree. You also eliminate the
chance of getting the wrong scope.
You also get full de-coupling of a
controller/directive from a
particular place in your app. Use it
anywhere, $broadcast() everywhere.

Friday, November 15, 13
Angular Events to
The Rescue!!!
And you don’t even need to predict
who all the recipients will be. By
sending:
$rootScope.$broadcast(‘gameOver’)
your whole app gets the information,
You can consume the event as many
places as you like, with:
$scope.$on(‘gameOver’, handlerFunc)

Friday, November 15, 13
Directives
DEMO BREAKDOWN 3:
ActiveTab

Friday, November 15, 13
CODA

Friday, November 15, 13
2 Excellent New
Tutorials:
ng-newsletter’s “Beginner to Expert”
series: http://www.ng-newsletter.com/
posts/beginner2experthow_to_start.html
Thinkster.IO’s “A Better Way to Learn
AngularJS”: http://www.thinkster.io/
pick/GtaQ0oMGIl/a-better-way-tolearn-angularjs

Friday, November 15, 13
Must-Use Learning
Collection
AngularJS-Learning: https://
github.com/jmcunningham/AngularJSLearning

Friday, November 15, 13
Angular 1.2 New
Features
http://docs.angularjs.org/guide/
migration
AngularJS 1.2 and Beyond - YouTube:
http://www.youtube.com/watch?
v=W13qDdJDHp8
(transcript of video, with slides: http://
fastandfluid.com/PublicDownloads/
AngularV1.2AndBeyond_2013-06-11.pdf)

Friday, November 15, 13
Angular 1.2 New
Features
The new animations, in particular,
are super-righteous: declare standard
CSS animations in classes, then
Angular will apply them while
migrating content in and out of the
DOM.

Friday, November 15, 13
Thank You!
about.me/XML

Friday, November 15, 13

More Related Content

What's hot (20)

PDF
Angular 10 course_content
NAVEENSAGGAM1
 
PPTX
Visitor Pattern
Ider Zheng
 
PPT
Angular Introduction By Surekha Gadkari
Surekha Gadkari
 
PPTX
Design Patterns - Abstract Factory Pattern
Mudasir Qazi
 
PPTX
Selenium-Locators
Mithilesh Singh
 
PDF
Swift in SwiftUI
Bongwon Lee
 
PPTX
Facade Design Pattern
Livares Technologies Pvt Ltd
 
PPTX
Angular 9
Raja Vishnu
 
PPTX
Bloc Pattern - Practical Use Cases - Flutter London - 21JAN2019
Didier Boelens
 
PPTX
React JS part 1
Diluka Wittahachchige
 
PPTX
Angular modules in depth
Christoffer Noring
 
PDF
Vue.js
Jadson Santos
 
PDF
Swift Tutorial Part 1. The Complete Guide For Swift Programming Language
Hossam Ghareeb
 
PPT
Selenium
Sun Technlogies
 
PPTX
Angular 5 presentation for beginners
Imran Qasim
 
PPTX
Clean architecture on android
Benjamin Cheng
 
PPTX
Android MVVM
David Estivariz Pierola
 
PPT
Command Design Pattern
Shahriar Hyder
 
PPTX
Dependency injection ppt
Swati Srivastava
 
PPTX
Clean Architecture
Zahra Heydari
 
Angular 10 course_content
NAVEENSAGGAM1
 
Visitor Pattern
Ider Zheng
 
Angular Introduction By Surekha Gadkari
Surekha Gadkari
 
Design Patterns - Abstract Factory Pattern
Mudasir Qazi
 
Selenium-Locators
Mithilesh Singh
 
Swift in SwiftUI
Bongwon Lee
 
Facade Design Pattern
Livares Technologies Pvt Ltd
 
Angular 9
Raja Vishnu
 
Bloc Pattern - Practical Use Cases - Flutter London - 21JAN2019
Didier Boelens
 
React JS part 1
Diluka Wittahachchige
 
Angular modules in depth
Christoffer Noring
 
Swift Tutorial Part 1. The Complete Guide For Swift Programming Language
Hossam Ghareeb
 
Selenium
Sun Technlogies
 
Angular 5 presentation for beginners
Imran Qasim
 
Clean architecture on android
Benjamin Cheng
 
Command Design Pattern
Shahriar Hyder
 
Dependency injection ppt
Swati Srivastava
 
Clean Architecture
Zahra Heydari
 

Viewers also liked (8)

PDF
I'm Postal for Promises in Angular
Christian Lilley
 
PPTX
AngularJS is awesome
Eusebiu Schipor
 
PPT
Angular Seminar-js
Mindfire Solutions
 
PPTX
Live Demo : Trending Angular JS Featues
Edureka!
 
PDF
Angular JS - Develop Responsive Single Page Application
Edureka!
 
PDF
AngularJS - What is it & Why is it awesome ? (with demos)
Gary Arora
 
PDF
AngularJS Basics with Example
Sergey Bolshchikov
 
PPTX
Introduction to Angularjs
Manish Shekhawat
 
I'm Postal for Promises in Angular
Christian Lilley
 
AngularJS is awesome
Eusebiu Schipor
 
Angular Seminar-js
Mindfire Solutions
 
Live Demo : Trending Angular JS Featues
Edureka!
 
Angular JS - Develop Responsive Single Page Application
Edureka!
 
AngularJS - What is it & Why is it awesome ? (with demos)
Gary Arora
 
AngularJS Basics with Example
Sergey Bolshchikov
 
Introduction to Angularjs
Manish Shekhawat
 
Ad

Similar to Angular from Scratch (20)

PDF
Angularjs
Ynon Perek
 
PPTX
Angular js 1.3 presentation for fed nov 2014
Sarah Hudson
 
PDF
Tek 2013 - Building Web Apps from a New Angle with AngularJS
Pablo Godel
 
PDF
Building Better Web Apps with Angular.js (SXSW 2014)
kbekessy
 
PDF
AngularJS in Production (CTO Forum)
Alex Ross
 
PPTX
AngularJS Introduction (Talk given on Aug 5 2013)
Abhishek Anand
 
PPTX
Angular workshop - Full Development Guide
Nitin Giri
 
PDF
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
George Nguyen
 
PPTX
AngularJS One Day Workshop
Shyam Seshadri
 
PDF
Lone StarPHP 2013 - Building Web Apps from a New Angle
Pablo Godel
 
PDF
Angular.js for beginners
Basia Madej
 
PDF
gDayX - Advanced angularjs
gdgvietnam
 
PDF
AngularJS in practice
Eugene Fidelin
 
PDF
Nicolas Embleton, Advanced Angular JS
JavaScript Meetup HCMC
 
PDF
Quick start with AngularJS
Iuliia Baranova
 
PDF
Itroducing Angular JS
Carlos Emanuel Mathiasen
 
PDF
Yeoman AngularJS and D3 - A solid stack for web apps
climboid
 
PDF
Everything You Need To Know About AngularJS
Sina Mirhejazi
 
PDF
Intro to Angular.JS Directives
Christian Lilley
 
PPT
Introduction to AngularJS
Anass90
 
Angularjs
Ynon Perek
 
Angular js 1.3 presentation for fed nov 2014
Sarah Hudson
 
Tek 2013 - Building Web Apps from a New Angle with AngularJS
Pablo Godel
 
Building Better Web Apps with Angular.js (SXSW 2014)
kbekessy
 
AngularJS in Production (CTO Forum)
Alex Ross
 
AngularJS Introduction (Talk given on Aug 5 2013)
Abhishek Anand
 
Angular workshop - Full Development Guide
Nitin Giri
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
George Nguyen
 
AngularJS One Day Workshop
Shyam Seshadri
 
Lone StarPHP 2013 - Building Web Apps from a New Angle
Pablo Godel
 
Angular.js for beginners
Basia Madej
 
gDayX - Advanced angularjs
gdgvietnam
 
AngularJS in practice
Eugene Fidelin
 
Nicolas Embleton, Advanced Angular JS
JavaScript Meetup HCMC
 
Quick start with AngularJS
Iuliia Baranova
 
Itroducing Angular JS
Carlos Emanuel Mathiasen
 
Yeoman AngularJS and D3 - A solid stack for web apps
climboid
 
Everything You Need To Know About AngularJS
Sina Mirhejazi
 
Intro to Angular.JS Directives
Christian Lilley
 
Introduction to AngularJS
Anass90
 
Ad

Recently uploaded (20)

PDF
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PDF
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
PDF
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
PDF
Staying Human in a Machine- Accelerated World
Catalin Jora
 
PDF
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
DOCX
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PPTX
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
PPTX
Digital Circuits, important subject in CS
contactparinay1
 
PDF
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
PDF
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PPTX
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
PDF
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PDF
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
PPTX
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
How do you fast track Agentic automation use cases discovery?
DianaGray10
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
Transforming Utility Networks: Large-scale Data Migrations with FME
Safe Software
 
Future-Proof or Fall Behind? 10 Tech Trends You Can’t Afford to Ignore in 2025
DIGITALCONFEX
 
Staying Human in a Machine- Accelerated World
Catalin Jora
 
“Squinting Vision Pipelines: Detecting and Correcting Errors in Vision Models...
Edge AI and Vision Alliance
 
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Mastering ODC + Okta Configuration - Chennai OSUG
HathiMaryA
 
Digital Circuits, important subject in CS
contactparinay1
 
UPDF - AI PDF Editor & Converter Key Features
DealFuel
 
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
Agentforce World Tour Toronto '25 - Supercharge MuleSoft Development with Mod...
Alexandra N. Martinez
 
AI Agents in the Cloud: The Rise of Agentic Cloud Architecture
Lilly Gracia
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 

Angular from Scratch

  • 1. FROM SCRATCH! github.com/xmlilley/ng-demos @ Angular Meetup DC, 11/13/13 by: Christian Lilley about.me/XML Friday, November 15, 13 @XMLilley
  • 2. GOALS & ASSUMPTIONS • We’re all familiar with basic Javascript & HTML & MVC terminology, but maybe not Angular’s take on it. • Yeoman is awesome. But the Yeoman way and the basic (naïve) way aren’t really compatible in a 2-hr session. We’ll leave Yeoman for another day. •I wish there was more time for audience hands-on tonight, but Angular’s a big topic. So, all the demo code is available for take-home experimentation. • Save questions for breaks & the end, pls. I’ll stick around. Friday, November 15, 13
  • 3. ANGULAR BUZZWORDS Full Application Framework, not a Library • MV* • Convenient Abstractions • Total Modularity, Reusability • Pub-Sub Communications Between Modules • Dependency Injection • Routing, Deep-Linking, History • Filters, Expression Interpolation • Friday, November 15, 13 Data-Binding • HTML Templating • Testing Baked-In (Karma) • Integrated Promises ($Q) • Localization • Form Validation • “Big UI” • MIT License •
  • 4. ANGULAR IS ALL ABOUT... • MV*: A data model, templates for viewing/interacting with it, and logic in controllers, services, directives, etc. • Declarative Behavior: Protect Extend HTML. HTML is right for templates, not JS. Intentions are visible in templates. • Data-Binding: User or Program can modify the model, and views update automagically to reflect those changes. • Model-Driven Behavior: DOM / View updates based on model, not brittle imperative logic. Truth in DOM Model. • Modular Architecture, Separated Concerns: DOM changes in Directives, model changes in Controllers, abstracted app-wide support functions & data in Services Friday, November 15, 13
  • 7. Bootstrapping Your App The ng-app directive tells Angular what part of your main template it needs to watch. It ‘wakes up’ Angular. You can (should) define a specific Angular module to serve as the core app logic: ng-app=‘myModule’ You can also bootstrap manually, if you need to. Friday, November 15, 13
  • 8. Data-Binding Angular’s declarative 2-way databinding is part of its special sauce. Changing data automagically Changing data automagically in the model updates the view. in the view updates the model. model -> view -> model -> view LET ANGULAR DO THIS FOR YOU! It’s part of Angular’s emphasis on model-driven UI. Friday, November 15, 13
  • 9. DOM Then shows final outcome in the DOM Angular watches for changes here Don’t do imperative DOM Changes! Consequent model changes by Angular MODEL Model Changes can start anywhere Friday, November 15, 13 Updates the model accordingly Truth lives Here! Not in DOM!
  • 10. Tells Angular: “Watch this space” Tells Angular: “Bind this input.” Tells Angular: “Insert Data here.” Friday, November 15, 13
  • 11. But what about those curly-brackets? ANGULAR EXPRESSIONS Friday, November 15, 13
  • 12. With an Angular Expression, You Can: Do math, or comparison Concatenate text Reference a model property Invoke a function But not: Control Flow, like conditions or loops (app logic belongs in controllers) Friday, November 15, 13
  • 13. One more thing you can do: Filter the output of the expression Filters are applied by ‘piping’ an expression into one: {{modelName.propertyName  |  filterName:arg}} Friday, November 15, 13
  • 14. DEMO DEMO DEMO Friday, November 15, 13
  • 15. So, How Can we Build a More Complicated App Than This? Organize code with MODULES Friday, November 15, 13
  • 16. Modules are where we put our code: like filters, controllers, directives, services, and configuration information. They provide us with encapsulation and re-usability for macro-level groupings of code. Note that angular.module(‘moduleName’) is both a creator and a retriever. Friday, November 15, 13
  • 17. And when we want to organize our data (view-models), too? Organize view data & functions with CONTROLLERS Friday, November 15, 13
  • 18. Controllers Intro Controllers are function Instances, used for interacting w/ data in views: They’re created and destroyed along with elements/templates. multiple invocations = multiple instances If you want persistence, either place on an element that’s persistent, or place the data/methods in a service (more later). Hard to address a *specific* controller, so use events for communication (more later). Friday, November 15, 13
  • 19. DEMO DEMO DEMO Friday, November 15, 13
  • 20. Services Intro Services are ludicrously simple: Remember (from, like, 1 slide ago), how controllers are created and destroyed every time you need one? And there can be lots of instances of a single controller type? Services, by contrast, are unicorns, and last forever. (jargon: ‘lazy-loaded singletons’) Friday, November 15, 13
  • 21. Templates/Views Intro In Angular, HTML is the template language! Use inline HTML, external files, or simple strings as templates. Then use expressions (and directives) to insert data from your model into the view. Re-use templates with different controllers, re-use controllers with different templates. Friday, November 15, 13
  • 22. DEMO DEMO DEMO Friday, November 15, 13
  • 23. Routing Intro Since we’re extending HTML in our templates, let’s extend the browser too. Routing lets you drive your interface views using the content of the location/URL bar. This lets our Angular Apps behave just like the server-side apps that users are used to, with forward/back and deep-linking to specific content. Friday, November 15, 13
  • 24. DEMO DEMO DEMO Friday, November 15, 13
  • 25. Directives Intro Controllers are just for data interactions. So DOM code has to go somewhere. Directives it is. Modular, re-usable, de-coupled DOM logic. Directives embody all of Angular’s major design principles. Way easier to use than the (old) Angular docs make it seem. We’ll have you writing your own in no time. Friday, November 15, 13
  • 26. Directive Pop-Star: NG-REPEAT Everybody digs it: throw a series of data into your view super-easily. Like ‘collection-views’ in other libraries filter/sort the output if you like Friday, November 15, 13
  • 27. DEMO DEMO DEMO Friday, November 15, 13
  • 28. Coming up... the DEETS First... Questions? Friday, November 15, 13
  • 29. CONTROLLERS In (a smidge more) Detail Friday, November 15, 13
  • 30. About Controllers Best-practice: use controller only for dealing with data/model. Let directives handle updating the views based on the properties of the model. Two ways to define: using .controller() method on a module As an ordinary named function (This will wind up on global scope. No good reason to do this. Just recognize it if you see it.) Friday, November 15, 13
  • 32. Templates Demo Note: when we provide the name of a template in the declaration of a directive like ng-include, we have to wrap it in a second pair of quotes. The first pair of quotes delimits an expression, which will be eval()’d by Angular. Since we supply a template path as a string, it needs the quotes. We could also reference a property on the model, without needing to do that. Friday, November 15, 13
  • 33. Templates/Views We can include templates conditionally, using directives like ng-show/ng-hide, ng-if, ng-switch (We’ll also demonstrate how to use custom directives as another way to include a template.) But the most powerful way to conditionally show content, is to use the browser’s address bar. Which means we want... Friday, November 15, 13
  • 34. Templates SNAFU Browsers don’t like to let you access external local files. This sets off ‘sameorigin’ errors. Simple solution: start a server. Painless Javascript/Node approach: >>  sudo  npm  install  -­‐g  http-­‐server >>  http-­‐server  (or:  `node  bin/http-­‐server`) But, no logging! ‘Ole-reliable Python option with logging: >>  python  -­‐m  SimpleHTTPServer  8000 Or, the faster ‘Twisted’ (comes w/ OSX): >>  twistd  -­‐no  web  -­‐-­‐path=. Friday, November 15, 13
  • 35. Templates SNAFU Or, you can just use Yeoman/Grunt: >>  grunt  server (do this) Friday, November 15, 13
  • 37. First: $location Angular’s $location service is bound to window.location (ie. to what’s in the browser’s ‘address bar’) Changes to the URL in the address bar are reflected in $location & changes to $location are reflected in address bar. ‘Back’ & ‘Forward’ are supported, as is deep-linking See: “Using $location” guide Friday, November 15, 13
  • 38. $route The $route service (configured via $routeProvider) gives us the ability to react programmatically to changes in the $location (plus $routeParams). We specify a template that will be rendered inside an <ng-view> in response to a given route-change, along with its controller and some other details. Friday, November 15, 13
  • 39. Routing Is A Config For Your App Module Fundamentally, routing works as a configuration detail on your base application module. (The one in ng-app.) There are two ways to configure your app: by supplying a config function at module creation, or by invoking the config function on your app after creation... Friday, November 15, 13
  • 40. 2 Ways to Config App A config function is the (unpopular) third argument to a module’s creation: myModule = angular.module(name, [dependencies], function(injectables) { // Configuration details, like routing }); Or, after the fact w/ Module.config( ) myModule.config(function(injectables) { // Configuration details, like routing }); Friday, November 15, 13
  • 41. Routing Syntax Routes are added via configuration methods called on $routeProvider in the app config function. There are only two basic methods involved: $routeProvider.when(path, route) $routeProvider.otherwise(params) Friday, November 15, 13
  • 42. Route Config Object We can include an optional route config object for each path, with the following options: template: html template as string templateUrl: path to a partial controller: binds an instance of specified controller to the template instance redirectTo: a path string or a function that returns one resolve: a function or service reference that will execute (or promise that resolves) before $routeChangeSuccess Friday, November 15, 13
  • 43. Routing Example myModule.config(function($routeProvider) { $routeProvider .when('/home', { templateUrl: 'home.html', controller: homeCtrl }) .when('/index', { redirectTo: '/home’ }) .when('/archive/doc/:docId', { templateUrl: 'archive_doc.html', controller: archCtrl }) .when('/contact', { templateUrl: 'poc.html', controller: pocCtrl, resolve: { // I will cause a 1 second delay delay: function($q, $timeout) { var delay = $q.defer(); $timeout(delay.resolve, 1000); return delay.promise; }}) .otherwise({ redirectTo: '/home' }); }); Friday, November 15, 13
  • 44. .otherwise() The only property in the .otherwise() config object is redirectTo NOTE: the value of redirectTo should be a path, like ‘/home’, not a template location like ‘home.html’. The route for ‘/home’ will then take care of supplying the template. myModule.config(function($routeProvider) { $routeProvider .when('/home', { templateUrl: 'home.html', controller: homeCtrl }) .otherwise({ redirectTo: '/home' }); }); Friday, November 15, 13
  • 45. Named Groups in Path The path can contain ‘named groups’ starting with a colon (/path/path/:name). All characters between colon and next slash are matched and stored in $routeParams. From $routeParams, you can access that data and use it in preparing the view, based on related data. Good technique for dynamically including data from a collection: users, products, chapters, etc. Friday, November 15, 13
  • 46. Named Groups in Path example definition from Angular docs: $routeProvider.when('/Book/:bookId/ch/:chapterId', {templateUrl: 'chapter.html', controller: ChapterCntl }); Example URL: //docs.angular.org/Book/Gatsby/ch/4 The Route Params you’ll see for that: $routeParams = {"bookId":"Moby","chapterId":"1"} Friday, November 15, 13
  • 47. $scope & Models In Detail Friday, November 15, 13
  • 48. ‘Models’ Unlike Ember, Angular doesn’t force you into creating OOP models using their abstractions. Do as you like. But model data should reside in objects that are properties on the $scope (‘model objects’, if you will), not directly in properties of the scope. Operations upon properties stored directly on $scope can have unexpected results. This is *totally* undocumented, but comes from Angular core team. Friday, November 15, 13
  • 49. WTF is $scope ??? So, if Angular models are just plainold Javascript objects (POJOs), what do we need this $scope thing for? Dependency Injection Angular will the correct, you need it: controllers, use DI to make sure that contextual data is where in re-usable directives & views. $scope also gives us inheritance, via a DOM-like tree. Data available to app root is also available on leaves. Friday, November 15, 13
  • 50. $rootScope Main/Nav Controller $scope View 1 Controller $scope Directive A-1 $scope Friday, November 15, 13 Directive B $scope Directive C can access all properties from all three parent scopes View 2 Controller $scope Directive A-2 $scope Directive C $scope
  • 51. Visualizing Scope Use the Angular Batarang!!! Friday, November 15, 13
  • 53. Services in Detail: Why Services? Provide re-usable, testable modular utilities across the application Abstract implementation details, and simply provide a convenient API to other parts of the application. Provide persistent application state across controller, view & directive *instances* Friday, November 15, 13
  • 54. Services in Detail ‘Back-office’ functions, like networking, event-dispatch, etc. Lazy-loaded singleton modules that persist through the life-cycle of the app, once instantiated. Injected dependencies that can be used by any other module Examples: $http, $log, $location, $route, & services used only by Angular: $provide, $injector, $parse Friday, November 15, 13
  • 55. Services: A Metaphor In some ways, an Angular Service is little more than a stateful, application-wide controller. Friday, November 15, 13
  • 56. How are custom Services different from built-ins? They’re not. At all. No, really. (Well, OK: they’re different in naming conventions: don’t use ‘$’ in your custom services.) Friday, November 15, 13
  • 57. Defining Services There are wayyy too many patterns for defining a service, and the Angular docs fail to even mention the simplest, most intuitive one, using the module’s .service() convenience method (which also aliases to .factory): var app = angular.module('appModule', ['dependency1']); app.service(‘serviceName’, function() { return shinyNewServiceInstance; }); Friday, November 15, 13
  • 58. Defining Services The older version of service creation, which you’ll still find in the docs, involves the module’s config function and calling .factory (or .service) on $provide: angular.module('appModule',[‘dependency1’]) .config(function($provide) { $provide.factory('serviceName', function() { return shinyNewServiceInstance; }); }); Friday, November 15, 13
  • 59. So, how crazy complicated is the service instance itself? Friday, November 15, 13
  • 60. shinyNewServiceInstance Relax! Here, we get to rely on standard JS pragmatics: return either a single function or a revealed module, as you wish allows public & private properties in the constructor Friday, November 15, 13
  • 61. Single-Function Service angular.module('appModule', [], function($provide) { $provide.factory('notifySvc', function() { var msgs = []; //private variable return function(msg) { //public function msgs.push(msg); if (msgs.length == 3) { alert(msgs.join("n")); msgs = []; } }; }); Just call with notifySvc(msg), after injecting into a controller or directive Friday, November 15, 13
  • 62. Multi-Property Service angular.module('appModule', []) .service('notifySvc', function() { var msgs = []; //private variable return { submit: function(msg) { msgs.push(msg); }, dump: function() { if (msgs.length == 3) { win.alert(msgs.join("n")); msgs = []; } }; }}); Just call with notifySvc.submit(msg) and notifySvc.dump() Friday, November 15, 13
  • 63. Service Instantiation Remember: Services are ‘lazy-loaded singletons’. That means the service instance won’t actually be created until you specifically need it. You tell Angular you need it by injecting it into a controller, directive, etc. Friday, November 15, 13
  • 64. Referencing Services In a directive or controller, you can have direct access to a service and its properties, assuming you have injected it properly. In HTML (an interpolated expression), you can’t reference until you’ve attached it to local $scope. So, in your controller: $scope.property = serviceName.serviceProperty; Friday, November 15, 13
  • 68. What Are They, Really? 5(-ish) words: Logic & Behavior For UI “...a way to teach HTML new tricks.” Anything in your app that touches DOM Examples: event-handling, behavior management, template pre-processing & insertion, data-binding, ‘Collection Views’, UI Widgets, conditional display, i18n & localization, etc. Friday, November 15, 13
  • 69. What Are They, Really? The only other Angular construct that really touches the DOM is: Angular Expressions (text only). Filters The rest of it should be in Directives. (Even the ng-view that executes your routing is simply a model-driven directive...) Friday, November 15, 13
  • 70. What Are They, Really? Structurally speaking, a Directive is just a function that’s attached to an element. But not just a function: a whole execution environment. Really, Directives are mini-applications. You can think of them as little robotic pilots that live on your DOM elements & tell them what to do. Friday, November 15, 13
  • 74. Angular isn’t just another way to organize the same old UI code!!! Friday, November 15, 13
  • 76. Why Declarative? IMPERATIVE = YOUR PROBLEM DECLARATIVE = SOMEBODY ELSE’S PROBLEM Easier To Read, Maintain: Why scatter event-listeners across 100 linked JS files, then need to go search for them to find out what’s happening on an element. Friday, November 15, 13
  • 77. Declarativeness ROCKS You’re trying to find handlers for this element: <button id=”1” class=”B C”></button> Well, where are the event-handlers? On ‘#1’? On ‘.B’? ‘.C’? On ‘button’? What if it’s on ‘parentDiv>:firstchild’? You can’t misunderstand what’s happening with declarative directives: <button md-action-handler></button> Friday, November 15, 13
  • 78. Extending HTML... HTML is NOT a virgin bride or hothouse flower. The Semantics Wars are over. HTML is a highly-abstracted, Object-Oriented language for app interfaces and for *presenting* documents. Docs themselves are increasingly stored in other formats, like markdown. We’re not abandoning accessibility. But it’s not a binary choice, anyway. Friday, November 15, 13
  • 79. Opinionated Principles 1.Declarative, Model-Driven Behavior 2.Modularity, Reusability across contexts: Write Once, Run Anywhere Friday, November 15, 13
  • 80. Reusability It’s all about context-awareness, data-binding & DI. Directives know their own element and local scope. You can pass additional data into directives as attributes, right on the element. Friday, November 15, 13
  • 81. <div id="header_tabs"> <a href="#/home" active-tab="1">HOME</a> <a href="#/finance" active-tab="1">Finance</a> <a href="#/hr" active-tab="1">Human Resources</a> <a href="#/quarterly" active-tab="1">Quarterly</a> </div> AND... <div id="subnav_tabs"> <a href="#/hr/pay" active-tab="2">Pay</a> <a href="#/hr/benefits" active-tab="2">Benefits</a> <a href="#/hr/help" active-tab="2">Help</a> </div> Friday, November 15, 13
  • 82. Opinionated Principles 1.Declarative, Model-Driven Behavior 2.Modularity, Reusability across contexts: Write Once, Run Anywhere 3.Keep it Local Friday, November 15, 13
  • 84. Yes: ‘Local’ Sticks to a self-contained, modular scope, which understands its context: inside the directive, `element` is like `this`. Uses messages, models to affect things elsewhere. Easier to maintain, easier to read, easier to scale. But the challenge to all that is: Friday, November 15, 13
  • 85. My Awesome Website Needs to Change Things Here Sweet Product Cart: 1 Item(s) $899.99 Buy Now! Product Description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum. Morbi gravida metus ut sapien condimentum sodales mollis augue sodales. Vestibulum quis quam at sem placerat aliquet. Curabitur a felis at sapien ullamcorper fermentum. Mauris molestie arcu et lectus iaculis sit amet eleifend eros posuere. Fusce nec porta orci. Clicking Here Friday, November 15, 13 Integer vitae neque odio, a sollicitudin lorem. Aenean orci mauris, tristique luctus fermentum eu, feugiat vel massa. Fusce sem
  • 86. Let’s Build Some! but first... Questions? Friday, November 15, 13
  • 87. Directive Names Angular uses a convention borrowed from other JS projects: names in HTML are hyphenated... <sample-directive></sample-directive> while identifiers in the JS are camel-cased: .directive(‘sampleDirective’, function(){}) Expect Angular to do this conversion automatically. Don’t fight it. Friday, November 15, 13
  • 88. How are custom directives different from built-in? They’re not. At all. No, really. (Well, OK: they’re different in naming conventions: don’t use ‘ng-’ in your custom directives.) Friday, November 15, 13
  • 89. CREATION .directive() is a method we call on an angular.module(), either at creation time or via reference, passing a name and a factory function angular .module('moduleName', ['dependency1', 'dependency2']) .directive('directiveName', factoryFunction() {}) The factory will return either a function or an object containing a function and other settings Friday, November 15, 13
  • 90. Factories (Note, when we talk about generic ‘factories’, we don’t mean $factory, which is an Angular implementation service.) The factory pattern is all about Functional Programming: using basic Javascript functions to build and return either naiive objects or other functions. Friday, November 15, 13
  • 91. What do We Do With The Factory Function? Friday, November 15, 13
  • 92. Two Basic Options: Return a Config Object or a ‘Linking Function’ Friday, November 15, 13
  • 95. You’ll See Later, But Ignore For Today: Returning only the Link function Link vs. Compile Pre-Link vs. Post-Link Friday, November 15, 13
  • 97. Using a Config Object angular.module('moduleName'). directive('sampleDirective', function(){ return { link: function(scope, element, attrs) { // this example binds a behavior to the // mouseenter event element.bind("mouseenter", function(){ ... do stuff after mouseenter ... } }, restrict: ‘E’, template: “<div>Hello, World!</div>” }}) Everything but `link` is optional. Friday, November 15, 13
  • 98. Link Function Args .directive('sampleDirective', function(){ return { link: function(scope, element, attrs) { // this example binds a behavior to the // mouseenter event element.bind("mouseenter", function(){ ... do stuff after mouseenter ... } }, restrict: ‘E’, template: <div>Hello, World!</div> } }) Friday, November 15, 13
  • 99. Link Function Args 3 standard params for a link function. (Plus optional 4th: controller.) They’re supplied as args by the directive function, if specified. scope: whatever scope object is local element: element declared on: `this` attrs: an object containing the html attributes defined on the element, including the directive invocation itself Supplied to the function not by name but in order. Call them whatever you want. Friday, November 15, 13
  • 100. jqLite: your path to the DOM Angular will defer to JQuery, if present, but provides its own subset of JQuery for basic DOM tasks. You can’t just use $(), nor find using selectors, unfortunately. But all built-in `element` refs are already pre-wrapped in jqlite object Chain methods as you normally would Friday, November 15, 13
  • 101. • • • • • • • • • • • • • • • addClass() after() append() attr() bind() children() clone() contents() css() data() eq() find() hasClass() html() next() on() Friday, November 15, 13 • • • • • • • • • • • • • • • • off() parent() prepend() prop() ready() remove() removeAttr() removeClass() removeData() replaceWith() text() toggleClass() triggerHandler() unbind() val() wrap()
  • 102. Using jqLite (angular.element) .directive('sampleDirective', function(){ return { link: function(scope, element, attrs) { // this example binds a behavior to the // mouseenter event element.bind("mouseenter", function(){ ... do stuff after mouseenter ... } }, restrict: ‘E’, template: <div>Hello, World!</div> }}) $(‘selector’).bind(‘mouseenter’, function() {}) Friday, November 15, 13
  • 103. ACK! THPPPT!! .bind() is ancient! Where’s .live() ?!? .on() ?!? Friday, November 15, 13
  • 105. A Thought: If angular.element() / jqlite doesn’t support what you’re trying to do... ask yourself: why not? Because they’re lazy bastards? Not so much. Think about other options. Go with the grain, and Angular will reward you. Friday, November 15, 13
  • 106. Directive Templates Templates can be stored as strings on the `template:` property They can also be loaded from a file, using: `templateUrl: path/to/file/template.html’ Friday, November 15, 13
  • 107. Templates .directive('sampleDirective', function(){ return { link: function(scope, element, attrs) { // this example binds a behavior to the // mouseenter event element.bind("mouseenter", function(){ ... do stuff after mouseenter ... } }, restrict: ‘E’, template: ‘<div>Hello, World!</div>’ //or: templateUrl: ‘path/to/file.html’ }) Friday, November 15, 13
  • 108. The Restrict Property .directive('sampleDirective', function(){ return { link: function(scope, element, attrs) { // this example binds a behavior to the // mouseenter event element.bind("mouseenter", function(){ ... do stuff after mouseenter ... } }, restrict: ‘E’, template: <div>Hello, World!</div> } }) Friday, November 15, 13
  • 109. The Restrict Property Remember that directives are re-usable So, we can restrict the usage of a directive to (a) specific context(s), so that we don’t accidentally try to use it in a situation it wasn’t designed for: ‘E’ = Element ‘A’ = Attribute ‘C’ = Class ‘M’ = Comment Stack as a single string: ‘EACM’. Defaults to ‘A’. Friday, November 15, 13
  • 110. The Replace Property By default, a directive element will wrap the contents of a template. The `element` object will be the outer directive element. To instead replace the directive element (and object) with the contents of the template, use {replace: true} This is esp critical when declaring as an element... Friday, November 15, 13
  • 112. So, about that: Model-Driven & Local Directive Design... Friday, November 15, 13
  • 114. Why Model-Driven? After all, the imperative approach works fine... ...if you’re omniscient and precognitive. ... and you really, really like refactoring. Friday, November 15, 13
  • 115. How Can Directives React to Models? With $watch! Friday, November 15, 13
  • 116. Directives DEMO BREAKDOWN 2: CLOCK (haha! Get it? We’re going to use a clock to demo $watch...) Friday, November 15, 13
  • 118. How Can Directives React to Stuff that Happens Far, Far Away? Again, with models & $watch! But sometimes, the inheritance chain isn’t a good solution. For those times... Angular events! $on(), $emit(), $broadcast() Friday, November 15, 13
  • 119. Advanced Topic: Inter-Scope Communication Use $watch to monitor properties of local $scope or one it inherits from That works great when you only need data to flow in one direction (up) and only on one branch of the tree. What about when you need to go downwards, or sideways? Or a whole bunch of places at once? Friday, November 15, 13
  • 120. $rootScope ??? Main/Nav Controller $scope ??? View 1 Controller $scope ??? ??? View 2 Controller $scope ??? Directive A-1 $scope Friday, November 15, 13 Directive B $scope Directive A-2 $scope Directive C $scope
  • 121. Angular Events to The Rescue!!! Just like how a ‘click’ event bubbles up through the DOM tree, you can $emit() an Angular event up the $scope tree, from any starting point. Better than the DOM, you can also $broadcast() an event down the $scope tree. $broadcast()-ing from $rootScope gets you the whole shebang. Friday, November 15, 13
  • 123. Angular Events to The Rescue!!! With events, there’s no need to laboriously climb your way up the $scope tree. You also eliminate the chance of getting the wrong scope. You also get full de-coupling of a controller/directive from a particular place in your app. Use it anywhere, $broadcast() everywhere. Friday, November 15, 13
  • 124. Angular Events to The Rescue!!! And you don’t even need to predict who all the recipients will be. By sending: $rootScope.$broadcast(‘gameOver’) your whole app gets the information, You can consume the event as many places as you like, with: $scope.$on(‘gameOver’, handlerFunc) Friday, November 15, 13
  • 127. 2 Excellent New Tutorials: ng-newsletter’s “Beginner to Expert” series: http://www.ng-newsletter.com/ posts/beginner2experthow_to_start.html Thinkster.IO’s “A Better Way to Learn AngularJS”: http://www.thinkster.io/ pick/GtaQ0oMGIl/a-better-way-tolearn-angularjs Friday, November 15, 13
  • 129. Angular 1.2 New Features http://docs.angularjs.org/guide/ migration AngularJS 1.2 and Beyond - YouTube: http://www.youtube.com/watch? v=W13qDdJDHp8 (transcript of video, with slides: http:// fastandfluid.com/PublicDownloads/ AngularV1.2AndBeyond_2013-06-11.pdf) Friday, November 15, 13
  • 130. Angular 1.2 New Features The new animations, in particular, are super-righteous: declare standard CSS animations in classes, then Angular will apply them while migrating content in and out of the DOM. Friday, November 15, 13