SlideShare a Scribd company logo
1 of 64
Download to read offline
Angular Directives
@ NationJS, 2013
by: Christian Lilley
about.me/xml @xmlilley
Friday, October 4, 13
What are Directives?
Friday, October 4, 13
Friday, October 4, 13
Angular, Ember, BackBone: Google Trends
Friday, October 4, 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, October 4, 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, October 4, 13
What AREN’T they?
Directives.
Are.
Not.
Where.
Your.
JQuery.
Goes!
Please,
God:
No.
Friday, October 4, 13
I
BUT...
Friday, October 4, 13
I
Moar
“The
Superheroic
MVW
framework.”
Friday, October 4, 13
And Angular isn’t
just another way to
organize the same
old UI code!!!
Friday, October 4, 13
Opinionated
Principles
1.Declarative, Model-Driven Behavior
Friday, October 4, 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, October 4, 13
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>
Friday, October 4, 13
Why NOT Declarative?
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 religion.
Friday, October 4, 13
1.Declarative, Model-Driven Behavior
2.Modularity, Reusability across
contexts: Write Once, Run Anywhere
Opinionated
Principles
Friday, October 4, 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, October 4, 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, October 4, 13
1.Declarative, Model-Driven Behavior
2.Modularity, Reusability across
contexts: Write Once, Run Anywhere
3.Keep it Local
Opinionated
Principles
Friday, October 4, 13
No...
Friday, October 4, 13
Yes: ‘Local’
Sticks to a self-contained, modular
scope, which understands its context.
Uses messages, models to affect
things elsewhere.
Easier to maintain, easier to read,
easier to scale.
But the challenge is this:
Friday, October 4, 13
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
eu, feugiat vel massa. Fusce sem
$899.99 Buy Now!
Cart: 1 Item(s)
Clicking Here
Needs to
Change
Things Here
Friday, October 4, 13
Let’s Build Some!
Friday, October 4, 13
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>
Friday, October 4, 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, October 4, 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
The factory will return either a
function or an object containing a
function and other settings
angular
.module('moduleName', ['dependency1', 'dependency2'])
.directive('directiveName', factoryFunction() {})
Friday, October 4, 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, October 4, 13
What do We Do With
The Factory
Function?
Friday, October 4, 13
Two Basic Options:
Return a
Config Object or a
‘Linking Function’
Friday, October 4, 13
Friday, October 4, 13
Friday, October 4, 13
You’ll See Later, But
Ignore For Today:
Returning only the Link
function
Link vs. Compile
Pre-Link vs. Post-Link
Friday, October 4, 13
Friday, October 4, 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, October 4, 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, October 4, 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, October 4, 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, October 4, 13
• 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()
Friday, October 4, 13
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, October 4, 13
ACK! THPPPT!!
.bind() is ancient!
Where’s .live() ?!?
.on() ?!?
Friday, October 4, 13
Friday, October 4, 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, October 4, 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, October 4, 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, October 4, 13
DEMO BREAKDOWN 1
Friday, October 4, 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, October 4, 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, October 4, 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, October 4, 13
DEMO BREAKDOWN 2
Friday, October 4, 13
So, about that:
Model-Driven & Local
Directive Design...
Friday, October 4, 13
Specifically, the
Model-Driven
part...
Friday, October 4, 13
Why Model-Driven?
After all, the imperative
approach works fine...
...if you’re omniscient
and precognitive.
... and you really, really
like refactoring.
Friday, October 4, 13
How Can Directives
React to Models?
With $watch!
Friday, October 4, 13
DEMO BREAKDOWN 3:
CLOCK
haha! Get it? We’re going to use
a clock to demo $watch...
Friday, October 4, 13
Keeping Directive
Design Local
Friday, October 4, 13
How Can Directives
React to Stuff that
Happens Far, Far Away?
Also, with models & $watch!
But sometimes, the inheritance
chain isn’t a good solution. For
those times...
Angular events!
$on(), $emit(), $broadcast()
Friday, October 4, 13
DEMO BREAKDOWN 4:
ActiveTab
Friday, October 4, 13
Often Overlooked:
Controllers
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
Friday, October 4, 13
Often Overlooked:
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.
Friday, October 4, 13
Isolate Scope
We have the option, in directives, of
using either:
the local $scope (from our
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
Friday, October 4, 13
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: “@”}
}})
Friday, October 4, 13
Cool!
But what’s that
‘@’ doing there?
Friday, October 4, 13
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() {},
restrict: ‘E’,
scope: {name: “Bob”,
hobby: “@”}
//alt. form:{pasttime: ‘@hobby’}
}})
<sample-directive hobby=”scuba-diving”>
Friday, October 4, 13
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.
Friday, October 4, 13
Thank You!
about.me/xml
Friday, October 4, 13

More Related Content

What's hot

AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developers
Kai Koenig
 

What's hot (20)

AngularJS Animations
AngularJS AnimationsAngularJS Animations
AngularJS Animations
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developers
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JS
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
AngularJS Basics with Example
AngularJS Basics with ExampleAngularJS Basics with Example
AngularJS Basics with Example
 
AngularJs $provide API internals & circular dependency problem.
AngularJs $provide API internals & circular dependency problem.AngularJs $provide API internals & circular dependency problem.
AngularJs $provide API internals & circular dependency problem.
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile Services
 
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
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
 
AngulrJS Overview
AngulrJS OverviewAngulrJS Overview
AngulrJS Overview
 
AngularJS Compile Process
AngularJS Compile ProcessAngularJS Compile Process
AngularJS Compile Process
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
 
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 Framework
AngularJS FrameworkAngularJS Framework
AngularJS Framework
 
AngularJS $Provide Service
AngularJS $Provide ServiceAngularJS $Provide Service
AngularJS $Provide Service
 
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
 
AngularJS Routing
AngularJS RoutingAngularJS Routing
AngularJS Routing
 
AngularJS Services
AngularJS ServicesAngularJS Services
AngularJS Services
 
AngularJS Basic Training
AngularJS Basic TrainingAngularJS Basic Training
AngularJS Basic Training
 
jQuery basics
jQuery basicsjQuery basics
jQuery basics
 

Similar to Intro to Angular.JS Directives

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
 
2a-JQuery AJAX.pptx
2a-JQuery AJAX.pptx2a-JQuery AJAX.pptx
2a-JQuery AJAX.pptx
Le Hung
 
Jquery Plugin
Jquery PluginJquery Plugin
Jquery Plugin
Ravi Mone
 

Similar to Intro to Angular.JS Directives (20)

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 ...
 
Why using finalizers is a bad idea
Why using finalizers is a bad ideaWhy using finalizers is a bad idea
Why using finalizers is a bad idea
 
The Theory Of The Dom
The Theory Of The DomThe Theory Of The Dom
The Theory Of The Dom
 
Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
 
Building a Bibliography
Building a BibliographyBuilding a Bibliography
Building a Bibliography
 
Scalable JavaScript Design Patterns
Scalable JavaScript Design PatternsScalable JavaScript Design Patterns
Scalable JavaScript Design Patterns
 
2a-JQuery AJAX.pptx
2a-JQuery AJAX.pptx2a-JQuery AJAX.pptx
2a-JQuery AJAX.pptx
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
jQuery Performance Tips and Tricks (2011)
jQuery Performance Tips and Tricks (2011)jQuery Performance Tips and Tricks (2011)
jQuery Performance Tips and Tricks (2011)
 
Backbone beyond jQuery
Backbone beyond jQueryBackbone beyond jQuery
Backbone beyond jQuery
 
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)
 
Backbone
BackboneBackbone
Backbone
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
Future-proofing Your JavaScript Apps (Compact edition)
Future-proofing Your JavaScript Apps (Compact edition)Future-proofing Your JavaScript Apps (Compact edition)
Future-proofing Your JavaScript Apps (Compact edition)
 
Jquery Plugin
Jquery PluginJquery Plugin
Jquery Plugin
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
AngularJS Custom Directives
AngularJS Custom DirectivesAngularJS Custom Directives
AngularJS Custom Directives
 
Modern JavaScript Programming
Modern JavaScript Programming Modern JavaScript Programming
Modern JavaScript Programming
 
13488117.ppt
13488117.ppt13488117.ppt
13488117.ppt
 
13488117.ppt
13488117.ppt13488117.ppt
13488117.ppt
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Recently uploaded (20)

Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

Intro to Angular.JS Directives

  • 1. Angular Directives @ NationJS, 2013 by: Christian Lilley about.me/xml @xmlilley Friday, October 4, 13
  • 4. Angular, Ember, BackBone: Google Trends Friday, October 4, 13
  • 5. 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, October 4, 13
  • 6. 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, October 4, 13
  • 10. And Angular isn’t just another way to organize the same old UI code!!! Friday, October 4, 13
  • 12. 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, October 4, 13
  • 13. 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> Friday, October 4, 13
  • 14. Why NOT Declarative? 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 religion. Friday, October 4, 13
  • 15. 1.Declarative, Model-Driven Behavior 2.Modularity, Reusability across contexts: Write Once, Run Anywhere Opinionated Principles Friday, October 4, 13
  • 16. 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, October 4, 13
  • 17. <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, October 4, 13
  • 18. 1.Declarative, Model-Driven Behavior 2.Modularity, Reusability across contexts: Write Once, Run Anywhere 3.Keep it Local Opinionated Principles Friday, October 4, 13
  • 20. Yes: ‘Local’ Sticks to a self-contained, modular scope, which understands its context. Uses messages, models to affect things elsewhere. Easier to maintain, easier to read, easier to scale. But the challenge is this: Friday, October 4, 13
  • 21. 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 eu, feugiat vel massa. Fusce sem $899.99 Buy Now! Cart: 1 Item(s) Clicking Here Needs to Change Things Here Friday, October 4, 13
  • 23. 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> Friday, October 4, 13
  • 24. 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, October 4, 13
  • 25. 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() {}) Friday, October 4, 13
  • 26. 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, October 4, 13
  • 27. What do We Do With The Factory Function? Friday, October 4, 13
  • 28. Two Basic Options: Return a Config Object or a ‘Linking Function’ Friday, October 4, 13
  • 31. You’ll See Later, But Ignore For Today: Returning only the Link function Link vs. Compile Pre-Link vs. Post-Link Friday, October 4, 13
  • 33. 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, October 4, 13
  • 34. 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, October 4, 13
  • 35. 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, October 4, 13
  • 36. 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, October 4, 13
  • 37. • 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() Friday, October 4, 13
  • 38. 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, October 4, 13
  • 39. ACK! THPPPT!! .bind() is ancient! Where’s .live() ?!? .on() ?!? Friday, October 4, 13
  • 41. 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, October 4, 13
  • 42. 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, October 4, 13
  • 43. 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, October 4, 13
  • 44. DEMO BREAKDOWN 1 Friday, October 4, 13
  • 45. 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, October 4, 13
  • 46. 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, October 4, 13
  • 47. 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, October 4, 13
  • 48. DEMO BREAKDOWN 2 Friday, October 4, 13
  • 49. So, about that: Model-Driven & Local Directive Design... Friday, October 4, 13
  • 51. Why Model-Driven? After all, the imperative approach works fine... ...if you’re omniscient and precognitive. ... and you really, really like refactoring. Friday, October 4, 13
  • 52. How Can Directives React to Models? With $watch! Friday, October 4, 13
  • 53. DEMO BREAKDOWN 3: CLOCK haha! Get it? We’re going to use a clock to demo $watch... Friday, October 4, 13
  • 55. How Can Directives React to Stuff that Happens Far, Far Away? Also, with models & $watch! But sometimes, the inheritance chain isn’t a good solution. For those times... Angular events! $on(), $emit(), $broadcast() Friday, October 4, 13
  • 57. Often Overlooked: Controllers 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 Friday, October 4, 13
  • 58. Often Overlooked: 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. Friday, October 4, 13
  • 59. Isolate Scope We have the option, in directives, of using either: the local $scope (from our 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 Friday, October 4, 13
  • 60. 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: “@”} }}) Friday, October 4, 13
  • 61. Cool! But what’s that ‘@’ doing there? Friday, October 4, 13
  • 62. 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() {}, restrict: ‘E’, scope: {name: “Bob”, hobby: “@”} //alt. form:{pasttime: ‘@hobby’} }}) <sample-directive hobby=”scuba-diving”> Friday, October 4, 13
  • 63. 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. Friday, October 4, 13