SlideShare a Scribd company logo
1 of 88
Download to read offline
Angular Directives
!
by: Christian Lilley
about.me/xml @xmlilley
Demos Repo: 

github.com/xmlilley/ng-demos
What are Directives?
Fine. How about…
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.
The only other Angular construct that
really touches the DOM is:	
Angular Expressions.	
The rest of it should be in
Directives. (Even the ng-view that
executes your routing is simply a
model-driven directive...)
Fine. How about…
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.
Fine. How about…
They can BYO DOM, or just be declared
on inline DOM.
Fine. How about…
What AREN’T they?
Directives.	
Aren’t.	
Just.	
Where.	
Your.	
JQuery.	
Goes!	
Please,	
God: 	
No.
I
BUT...
I
Moar
“The
Superheroic
MVW
framework.”
Angular isn’t just
another way to
organize the same
old UI code!!!
Opinionated
Principles	
1. Declarative, Model-Driven
Behavior
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.
Declarativeness ROCKS
You’re trying to find handlers for
this element:

Well, where are the event-handlers?
On ‘#1’? On ‘.B’? ‘.C’? On ‘button’?
What if it’s on ‘parentDiv>:first-
child’?	
You can’t misunderstand what’s
happening with declarative directives:
<button id=”1” class=”B C”></button>
<button md-action-handler></button>
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.
Opinionated
Principles	
1. Declarative, Model-Driven
Behavior 	
2. Modularity, Reusability
across contexts: Write Once,
Run Anywhere
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.
<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>
1. Declarative, Model-Driven
Behavior 	
2. Modularity, Reusability
across contexts: Write Once,
Run Anywhere	
3. Keep it Local
Opinionated
Principles
No...
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:
My Awesome Website
Sweet Product
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.	
!
Integer vitae neque odio, a
sollicitudin lorem. Aenean orci
mauris, tristique luctus fermentum
$899.99 Buy Now!
Cart: 1 Item(s)
Clicking Here
Needs to
Change
Things Here
Let’s Build Some!
Directive Names
Angular uses a convention borrowed
from other JS projects: names in HTML
are hyphenated...



while identifiers in the JS are
camel-cased:	
!
Expect Angular to do this conversion
automatically. Don’t fight it.
.directive(‘sampleDirective’, function(){})
<sample-directive></sample-directive>
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.)
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





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

.module('moduleName', ['dependency1', 'dependency2'])	
.directive('directiveName', factoryFunction() {})
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.
What do We Do With
That Factory
Function?
Two Basic Options:
Return a
Config Object or a
‘Linking Function’
You’ll See Later, But
Ignore For Today:
Returning only the Link
function	
Link vs. Compile	
Pre-Link vs. Post-Link

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.
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>	
	 }	
})
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.
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
addClass()

after()

append()

attr()

bind() 

children()

clone()

contents()

css()

data()

eq()

find() 

hasClass()

html()

next()

on() 

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() {})
ACK! THPPPT!!!
!
.bind() is ancient!
!
Where’s .live() ?!?
!
.on() ?!?
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.
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’
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’	
})
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>	
	 }	
})
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’.
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...
Directives
DEMO BREAKDOWN 1:
Enter-Leave
So, about that:
Model-Driven & Local
Directive Design...
Specifically, the
Model-Driven
part...
Why Model-Driven?
After all, the imperative
approach works fine... 	
...if you’re omniscient
and precognitive.	
... and you really, really
like refactoring.
Comparative Click-
Handlers: Imperative
“Do a whole bunch of stuff in
response to that click. Remember all
the things it should affect. Update
all those things. Try hard (and fail)
to do so without reading state from
the UI. Try hard (and fail) to
decompose these changes into reusable
functions. Try hard (and fail) to
make them declarative so I can easily
understand and maintain what's
happening."
Comparative Click-
Handlers: Angular
“Update some data, and/or send out a
notification. Done.” (Everything else
will happen in directives on the
affected elements.)	
In those other directives: “react to
received events, or to data-changes.
Change only what’s local to the
element.”
How Can Directives
React to Models?
With $watch!
Directives
DEMO BREAKDOWN 2:
CLOCK
(haha! Get it? We’re going to use

a clock to demo $watch...)
Keeping Directive
Design Local
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()
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?
$rootScope
Main/Nav
Controller	
$scope
View 1
Controller	
$scope
View 2
Controller	
$scope
Directive A-1	
$scope
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.
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.
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)
Directives
DEMO BREAKDOWN 3:
ActiveTab
Directives
DEMO BREAKDOWN 4:
ClickDetect
And if we have time…
`$scope` vs. `scope`
$scope is assignable, but should be
reserved for angular functions to pass
into a controller, other context.	
$scope is a shorthand, by which we're
calling the $scopeProvider, which is
Dependency-Injecting the scope for us.
There is a long-form that looks like
AMD, which is necessary when minifying,
so identifiers don't get munged. 	
scope is just our own, customizable
reference for directive’s local scope.
Link & Compile
Angular’s process for assembling a
page divides the work into multiple
phases: compile & link (pre- & post-)	
Directives have a function for each
step	
Think of link & compile like events, &
your functions firing as handlers	
We usually only need the link
function.
Link vs. Compile
Compile: “deals with transforming the
template DOM. Since most directives do not
do template transformation, it is not used
often. Examples that require compile are
directives that transform template DOM,
such as ngRepeat, or load the contents
asynchronously, such as ngView.” ie., it
grabs HTML assets and morphs them if
necessary. Rarely needed by users. 	
Link: “responsible for registering DOM
listeners as well as updating the DOM. It
is executed after the template has been
cloned.” ie., where everything else goes.
Using a Config Object
(compile version)
If we need to use a compile function,
that becomes the relevant property on
the config object, and we return the
link function from inside it.	
If we provide a value for the
`compile:` property, any value
provided for `link:` will be ignored.	
A compile function *must* return a link
function.
Using a Config Object
(compile version example)
.directive('sampleDirective', function(){	
	 return {	
compile: function(element, attrs) {	
... do compile stuff ...	
return function Link(scope, element, attrs)

{... do link stuff ...})	
	 },	
restrict: ‘E’,	
template: <div>Hello, World!</div>	
	 }	
})
And just to add more
complexity to that
structure...
Subdividing the Link
(config object example)
.directive('sampleDirective', function(){	
	 return {	
compile: function(element, attrs) {	
... do compile stuff ...	
return {	
pre: function(scope, element, attrs)

{... do pre-link stuff ...}, 	
post: function(scope, element, attrs)

{... do post-link stuff ...}	
}	
}}})
The link event actually consists of two
sub-events: pre-link and post-link,
which you can target:
Pre- vs. Post- Link
PRE-LINK: 

“Executed before the child elements are
linked. Not safe to do DOM transformation
since the compiler linking function will
fail to locate the correct elements for
linking.”	
POST-LINK: 

“Executed after the child elements are
linked. It is safe to do DOM transformation
in the post-linking function."	
But: don’t worry about these for now. Just
be aware of their existence, in case you see
them.
Back to challenging
but useful stuff...
Directive Config Objects can provide
an optional controller.	
At first, you think: why?	
One option: alternative to routing	
Routes have controllers	
Sometimes, you don’t want routes
Often Overlooked:
Directive Controllers
Often Overlooked:
Directive Controllers
With its own controller, a directive
is a full, standalone interface
component, with its own data context,
which can be built or torn-down on
demand.	
The controller inherits, normally,
from the rest of the $scope tree.
Isolate Scope
We have the option, in directives, of
using either: 	
the local $scope (from our own
controller, possibly)	
a new, per-instance, ‘isolate
scope’	
Isolate scopes still have a parent
$scope, but they’re *encapsulated*: or,
detached from the inheritance chain.	
This is especially useful with repeats,
so variables can be fully local to the
instance
Creating Isolate Scope
Creating isolate scope is as simple as
an object literal assigned to the
`scope:` property on the config object:
.directive('sampleDirective', function(){	
	 return {	
link: function(scope, element, attrs) {	
element.bind("mouseenter", function(){	
	 	 	 	 ... do stuff after mouseenter ...	
	 	 }	
},	
restrict: ‘E’,	
scope: {name: “Bob”,	
hobby: “@”}	
}})
Cool!
But what’s that
‘@’ doing there?
Isolate Scope Data-Binding
Angular provides us with ways to bind
the value of properties in isolate
scope to attributes on the element,
using special operators:
.directive('sampleDirective', function(){	
	 return {	
link: function(scope, element, attrs) {},	
restrict: ‘E’,	
scope: {name: “Bob”,	
hobby: “@”} 	
//alt. form:{hobby: ‘@hobby’}	
}})
<sample-directive hobby=”scuba-diving”>
Data-Binding Operators
By default, an operator alone will be
assumed to refer to a same-named attr	
Alternately, use form ‘@hobby’ to specify	
Options:	
‘@’- binds the local scope property to
primitive value of the DOM attribute. Result
is always a string. (Attributes are strings.)	
‘=’- binds the local scope property to a
parent scope property having same name as the
value of the DOM attribute.	
‘&’- binds the local scope property to the
output of an expression defined in the DOM
attribute. It’s like a function-wrapper.
Isolate Scope Data-Binding
The special operators make it seem more
exotic than it really is. For instance: 





…is basically the same as doing this in
your controller:





The difference is all in the fact that
isolate scope is disconnected from the
$scope tree, overrides local controller
$scope. Plus flexible eval()…
scope.hobby = attrs.hobby;
scope: {hobby: “@”}
Final Thoughts
Your directives can have directives.
(In them and on them.) Truly, it can
be directives all the way down…
Thank You!
!
about.me/XML

More Related Content

What's hot

AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developersKai Koenig
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsEPAM Systems
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgetsvelveeta_512
 
AngularJS custom directive
AngularJS custom directiveAngularJS custom directive
AngularJS custom directiveNascenia IT
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorialClaude Tech
 
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...Sencha
 
AngulrJS Overview
AngulrJS OverviewAngulrJS Overview
AngulrJS OverviewEyal Vardi
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Eventsdmethvin
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceParashuram N
 
Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.tothepointIT
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJSWei Ru
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationBuilding an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationDan Wahlin
 

What's hot (20)

AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developers
 
jQuery PPT
jQuery PPTjQuery PPT
jQuery PPT
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 
Getting the Most Out of jQuery Widgets
Getting the Most Out of jQuery WidgetsGetting the Most Out of jQuery Widgets
Getting the Most Out of jQuery Widgets
 
AngularJS custom directive
AngularJS custom directiveAngularJS custom directive
AngularJS custom directive
 
AngularJs
AngularJsAngularJs
AngularJs
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
 
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
SenchaCon 2016: Want to Use Ext JS Components with Angular 2? Here’s How to I...
 
jQuery basics
jQuery basicsjQuery basics
jQuery basics
 
AngulrJS Overview
AngulrJS OverviewAngulrJS Overview
AngulrJS Overview
 
AngularJS Basics with Example
AngularJS Basics with ExampleAngularJS Basics with Example
AngularJS Basics with Example
 
jQuery 1.7 Events
jQuery 1.7 EventsjQuery 1.7 Events
jQuery 1.7 Events
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.Using Renderless Components in Vue.js during your software development.
Using Renderless Components in Vue.js during your software development.
 
Get AngularJS Started!
Get AngularJS Started!Get AngularJS Started!
Get AngularJS Started!
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationBuilding an End-to-End AngularJS Application
Building an End-to-End AngularJS Application
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
jQuery
jQueryjQuery
jQuery
 

Similar to Angular Directives from Scratch

The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Domkaven yan
 
Hey, I just met AngularJS, and this is crazy, so here’s my JavaScript, let’s ...
Hey, I just met AngularJS, and this is crazy, so here’s my JavaScript, let’s ...Hey, I just met AngularJS, and this is crazy, so here’s my JavaScript, let’s ...
Hey, I just met AngularJS, and this is crazy, so here’s my JavaScript, let’s ...Alessandro Nadalin
 
Backbone beyond jQuery
Backbone beyond jQueryBackbone beyond jQuery
Backbone beyond jQueryAdam Krebs
 
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinWill your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinBarry Gervin
 
Make your Backbone Application dance
Make your Backbone Application danceMake your Backbone Application dance
Make your Backbone Application danceNicholas Valbusa
 
Angular js is the future. maybe. @ ConFoo 2014 in Montreal (CA)
Angular js is the future. maybe. @ ConFoo 2014 in Montreal (CA)Angular js is the future. maybe. @ ConFoo 2014 in Montreal (CA)
Angular js is the future. maybe. @ ConFoo 2014 in Montreal (CA)Alessandro Nadalin
 
AngularJS Custom Directives
AngularJS Custom DirectivesAngularJS Custom Directives
AngularJS Custom Directivesyprodev
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterpriseDave Artz
 
Functional Components in Vue.js
Functional Components in Vue.jsFunctional Components in Vue.js
Functional Components in Vue.jsAustin Gil
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
High performance websites session1
High performance websites  session1High performance websites  session1
High performance websites session1amr elgarhy
 
Modern frontend development with VueJs
Modern frontend development with VueJsModern frontend development with VueJs
Modern frontend development with VueJsTudor Barbu
 
Angular.js Directives for Interactive Web Applications
Angular.js Directives for Interactive Web ApplicationsAngular.js Directives for Interactive Web Applications
Angular.js Directives for Interactive Web ApplicationsBrent Goldstein
 

Similar to Angular Directives from Scratch (20)

The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Dom
 
Hey, I just met AngularJS, and this is crazy, so here’s my JavaScript, let’s ...
Hey, I just met AngularJS, and this is crazy, so here’s my JavaScript, let’s ...Hey, I just met AngularJS, and this is crazy, so here’s my JavaScript, let’s ...
Hey, I just met AngularJS, and this is crazy, so here’s my JavaScript, let’s ...
 
Backbone beyond jQuery
Backbone beyond jQueryBackbone beyond jQuery
Backbone beyond jQuery
 
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry GervinWill your code blend? : Toronto Code Camp 2010 : Barry Gervin
Will your code blend? : Toronto Code Camp 2010 : Barry Gervin
 
Make your Backbone Application dance
Make your Backbone Application danceMake your Backbone Application dance
Make your Backbone Application dance
 
Angular js is the future. maybe. @ ConFoo 2014 in Montreal (CA)
Angular js is the future. maybe. @ ConFoo 2014 in Montreal (CA)Angular js is the future. maybe. @ ConFoo 2014 in Montreal (CA)
Angular js is the future. maybe. @ ConFoo 2014 in Montreal (CA)
 
AngularJS Custom Directives
AngularJS Custom DirectivesAngularJS Custom Directives
AngularJS Custom Directives
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
 
Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
 
Functional Components in Vue.js
Functional Components in Vue.jsFunctional Components in Vue.js
Functional Components in Vue.js
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
High performance websites session1
High performance websites  session1High performance websites  session1
High performance websites session1
 
Modern frontend development with VueJs
Modern frontend development with VueJsModern frontend development with VueJs
Modern frontend development with VueJs
 
Intro to AngularJs
Intro to AngularJsIntro to AngularJs
Intro to AngularJs
 
AngularJs-training
AngularJs-trainingAngularJs-training
AngularJs-training
 
Data Binding
Data BindingData Binding
Data Binding
 
Angular.js Directives for Interactive Web Applications
Angular.js Directives for Interactive Web ApplicationsAngular.js Directives for Interactive Web Applications
Angular.js Directives for Interactive Web Applications
 
React & Flux Workshop
React & Flux WorkshopReact & Flux Workshop
React & Flux Workshop
 
AngularJs Crash Course
AngularJs Crash CourseAngularJs Crash Course
AngularJs Crash Course
 

Recently uploaded

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 

Recently uploaded (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 

Angular Directives from Scratch

  • 1. Angular Directives ! by: Christian Lilley about.me/xml @xmlilley Demos Repo: 
 github.com/xmlilley/ng-demos
  • 3.
  • 4.
  • 5. Fine. How about… 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.
  • 6. The only other Angular construct that really touches the DOM is: Angular Expressions. The rest of it should be in Directives. (Even the ng-view that executes your routing is simply a model-driven directive...) Fine. How about…
  • 7. 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. Fine. How about…
  • 8.
  • 9. They can BYO DOM, or just be declared on inline DOM. Fine. How about…
  • 10.
  • 14. Angular isn’t just another way to organize the same old UI code!!!
  • 16. 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.
  • 17. Declarativeness ROCKS You’re trying to find handlers for this element:
 Well, where are the event-handlers? On ‘#1’? On ‘.B’? ‘.C’? On ‘button’? What if it’s on ‘parentDiv>:first- child’? You can’t misunderstand what’s happening with declarative directives: <button id=”1” class=”B C”></button> <button md-action-handler></button>
  • 18. 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.
  • 19. Opinionated Principles 1. Declarative, Model-Driven Behavior 2. Modularity, Reusability across contexts: Write Once, Run Anywhere
  • 20. 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.
  • 21. <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>
  • 22. 1. Declarative, Model-Driven Behavior 2. Modularity, Reusability across contexts: Write Once, Run Anywhere 3. Keep it Local Opinionated Principles
  • 23. No...
  • 24. 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:
  • 25. My Awesome Website Sweet Product 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. ! Integer vitae neque odio, a sollicitudin lorem. Aenean orci mauris, tristique luctus fermentum $899.99 Buy Now! Cart: 1 Item(s) Clicking Here Needs to Change Things Here
  • 27. Directive Names Angular uses a convention borrowed from other JS projects: names in HTML are hyphenated...
 
 while identifiers in the JS are camel-cased: ! Expect Angular to do this conversion automatically. Don’t fight it. .directive(‘sampleDirective’, function(){}) <sample-directive></sample-directive>
  • 28. 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.)
  • 29. 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
 
 
 The factory will return either a function or an object containing a function and other settings angular
 .module('moduleName', ['dependency1', 'dependency2']) .directive('directiveName', factoryFunction() {})
  • 30. 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.
  • 31. What do We Do With That Factory Function?
  • 32. Two Basic Options: Return a Config Object or a ‘Linking Function’
  • 33.
  • 34.
  • 35. You’ll See Later, But Ignore For Today: Returning only the Link function Link vs. Compile Pre-Link vs. Post-Link

  • 36.
  • 37. 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.
  • 38. 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> } })
  • 39. 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.
  • 40. 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
  • 41. addClass() after() append() attr() bind() children() clone() contents() css() data() eq() find() hasClass() html() next() on() off() parent() prepend() prop() ready() remove() removeAttr() removeClass() removeData() replaceWith() text() toggleClass() triggerHandler() unbind() val() wrap()
  • 42. 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() {})
  • 43. ACK! THPPPT!!! ! .bind() is ancient! ! Where’s .live() ?!? ! .on() ?!?
  • 44.
  • 45. 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.
  • 46. 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’
  • 47. 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’ })
  • 48. 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> } })
  • 49. 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’.
  • 50. 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...
  • 52. So, about that: Model-Driven & Local Directive Design...
  • 54. Why Model-Driven? After all, the imperative approach works fine... ...if you’re omniscient and precognitive. ... and you really, really like refactoring.
  • 55. Comparative Click- Handlers: Imperative “Do a whole bunch of stuff in response to that click. Remember all the things it should affect. Update all those things. Try hard (and fail) to do so without reading state from the UI. Try hard (and fail) to decompose these changes into reusable functions. Try hard (and fail) to make them declarative so I can easily understand and maintain what's happening."
  • 56. Comparative Click- Handlers: Angular “Update some data, and/or send out a notification. Done.” (Everything else will happen in directives on the affected elements.) In those other directives: “react to received events, or to data-changes. Change only what’s local to the element.”
  • 57. How Can Directives React to Models? With $watch!
  • 58. Directives DEMO BREAKDOWN 2: CLOCK (haha! Get it? We’re going to use
 a clock to demo $watch...)
  • 60. 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()
  • 61. 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?
  • 62. $rootScope Main/Nav Controller $scope View 1 Controller $scope View 2 Controller $scope Directive A-1 $scope Directive B $scope Directive A-2 $scope Directive C $scope ??? ??? ??? ??? ???
  • 63. 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.
  • 64.
  • 65. 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.
  • 66. 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)
  • 69. And if we have time…
  • 70. `$scope` vs. `scope` $scope is assignable, but should be reserved for angular functions to pass into a controller, other context. $scope is a shorthand, by which we're calling the $scopeProvider, which is Dependency-Injecting the scope for us. There is a long-form that looks like AMD, which is necessary when minifying, so identifiers don't get munged. scope is just our own, customizable reference for directive’s local scope.
  • 71. Link & Compile Angular’s process for assembling a page divides the work into multiple phases: compile & link (pre- & post-) Directives have a function for each step Think of link & compile like events, & your functions firing as handlers We usually only need the link function.
  • 72. Link vs. Compile Compile: “deals with transforming the template DOM. Since most directives do not do template transformation, it is not used often. Examples that require compile are directives that transform template DOM, such as ngRepeat, or load the contents asynchronously, such as ngView.” ie., it grabs HTML assets and morphs them if necessary. Rarely needed by users. Link: “responsible for registering DOM listeners as well as updating the DOM. It is executed after the template has been cloned.” ie., where everything else goes.
  • 73. Using a Config Object (compile version) If we need to use a compile function, that becomes the relevant property on the config object, and we return the link function from inside it. If we provide a value for the `compile:` property, any value provided for `link:` will be ignored. A compile function *must* return a link function.
  • 74. Using a Config Object (compile version example) .directive('sampleDirective', function(){ return { compile: function(element, attrs) { ... do compile stuff ... return function Link(scope, element, attrs)
 {... do link stuff ...}) }, restrict: ‘E’, template: <div>Hello, World!</div> } })
  • 75. And just to add more complexity to that structure...
  • 76. Subdividing the Link (config object example) .directive('sampleDirective', function(){ return { compile: function(element, attrs) { ... do compile stuff ... return { pre: function(scope, element, attrs)
 {... do pre-link stuff ...}, post: function(scope, element, attrs)
 {... do post-link stuff ...} } }}}) The link event actually consists of two sub-events: pre-link and post-link, which you can target:
  • 77. Pre- vs. Post- Link PRE-LINK: 
 “Executed before the child elements are linked. Not safe to do DOM transformation since the compiler linking function will fail to locate the correct elements for linking.” POST-LINK: 
 “Executed after the child elements are linked. It is safe to do DOM transformation in the post-linking function." But: don’t worry about these for now. Just be aware of their existence, in case you see them.
  • 78. Back to challenging but useful stuff...
  • 79. Directive Config Objects can provide an optional controller. At first, you think: why? One option: alternative to routing Routes have controllers Sometimes, you don’t want routes Often Overlooked: Directive Controllers
  • 80. Often Overlooked: Directive Controllers With its own controller, a directive is a full, standalone interface component, with its own data context, which can be built or torn-down on demand. The controller inherits, normally, from the rest of the $scope tree.
  • 81. Isolate Scope We have the option, in directives, of using either: the local $scope (from our own controller, possibly) a new, per-instance, ‘isolate scope’ Isolate scopes still have a parent $scope, but they’re *encapsulated*: or, detached from the inheritance chain. This is especially useful with repeats, so variables can be fully local to the instance
  • 82. Creating Isolate Scope Creating isolate scope is as simple as an object literal assigned to the `scope:` property on the config object: .directive('sampleDirective', function(){ return { link: function(scope, element, attrs) { element.bind("mouseenter", function(){ ... do stuff after mouseenter ... } }, restrict: ‘E’, scope: {name: “Bob”, hobby: “@”} }})
  • 84. Isolate Scope Data-Binding Angular provides us with ways to bind the value of properties in isolate scope to attributes on the element, using special operators: .directive('sampleDirective', function(){ return { link: function(scope, element, attrs) {}, restrict: ‘E’, scope: {name: “Bob”, hobby: “@”} //alt. form:{hobby: ‘@hobby’} }}) <sample-directive hobby=”scuba-diving”>
  • 85. Data-Binding Operators By default, an operator alone will be assumed to refer to a same-named attr Alternately, use form ‘@hobby’ to specify Options: ‘@’- binds the local scope property to primitive value of the DOM attribute. Result is always a string. (Attributes are strings.) ‘=’- binds the local scope property to a parent scope property having same name as the value of the DOM attribute. ‘&’- binds the local scope property to the output of an expression defined in the DOM attribute. It’s like a function-wrapper.
  • 86. Isolate Scope Data-Binding The special operators make it seem more exotic than it really is. For instance: 
 
 
 …is basically the same as doing this in your controller:
 
 
 The difference is all in the fact that isolate scope is disconnected from the $scope tree, overrides local controller $scope. Plus flexible eval()… scope.hobby = attrs.hobby; scope: {hobby: “@”}
  • 87. Final Thoughts Your directives can have directives. (In them and on them.) Truly, it can be directives all the way down…