Custom Directives
Custom Directives
What are they?
- A mechanism to create custom HTML elements
- Similar to 'partials' but with the additional power of their own controller
- Can also be used like ng-bind to add specific functionality to any existing html element
Create a Directive
angular.module('SimpleDirectiveApp').directive('simpleCustomer', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}} '
};
});
In the simplest form you simply register a directive on your application:
In this case, customer must be available in the $scope of the controller that the directive lives in.
Create a Directive
<simple-customer ng-repeat="customer in customers"></simple-customer>
Including the directive in your HTML:
And for clarity, the controller:
angular.module('SimpleDirectiveApp', [])
.controller('MainController', function($scope) {
$scope.customers = [
{
name: 'Naomi',
address: '1600 Amphitheatre'
},
{
name: 'Tyler',
address: '1875 Texas Street'
},
{
name: 'Cookie Monster',
address: '1234 Cookie Street'
}
]
});
Create a Directive
<simple-customer ng-repeat="customer in customers"></simple-customer>
Angular turns our <simple-customer> tag into the template
angular.module('SimpleDirectiveApp').directive('simpleCustomer', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}} '
};
});
+
=
<simple-customer ng-repeat="customer in customers">
Name: {{customer.name}} Address: {{customer.address}}
</simple-customer>
Use an HTML template
Directives support the use of HTML files that act as partials
angular.module('SimpleDirectiveApp').directive('templateCustomer', function() {
return {
templateUrl: '/templates/customerTemplate.html'
};
});
customerTemplate.html
<div>
<h2>{{customer.name}}</h2>
<p>{{customer.address}}</p>
</div>
<hr>
Use an HTML template
Using <template-customer>
<div ng-repeat="customer in customers>
<h2>{{customer.name}}</h2>
<p>{{customer.address}}</p>
</div>
<hr>
<template-customer ng-repeat="customer in customers"></template-customer>
Which becomes
A Note on $scopes
- The previous two examples rely on the $scope of the controller in which they are defined -- which is not ideal
- We can use the link function, provided by Angular, to give directives a unique scope
Isolate Scope
angular.module('SimpleDirectiveApp').directive('isolateScopeCustomer', function() {
return {
scope: {
customerValues: '=customerValues',
},
templateUrl: '/templates/isolateScopeTemplate.html',
link: function(scope, element, attrs) {
scope.clickCount = 0;
scope.handleClick = function(){
scope.clickCount += 1;
}
}
};
});
scope defines how the directive receives information from the view. Note in the html customer-values="customer"
<isolate-scope-customer ng-repeat="customer in customers" customer-values="customer">
</isolate-scope-directive>
Isolate Scope
angular.module('SimpleDirectiveApp').directive('isolateScopeCustomer', function() {
return {
scope: {
customerValues: '=customerValues',
},
templateUrl: '/templates/isolateScopeTemplate.html',
link: function(scope, element, attrs) {
scope.clickCount = 0;
scope.handleClick = function(){
scope.clickCount += 1;
}
}
};
});
Note that we still have a templateUrl
<div ng-click="handleClick()">
<h2>{{customerValues.name}}</h2>
<p>{{customerValues.address}}</p>
<p>{{clickCount}}</p>
</div>
<hr>
isolateScopeTemplate.html
Isolate Scope
angular.module('SimpleDirectiveApp').directive('isolateScopeCustomer', function() {
return {
scope: {
customerValues: '=customerValues',
},
templateUrl: '/templates/isolateScopeTemplate.html',
link: function(scope) {
scope.clickCount = 0;
scope.handleClick = function(){
scope.clickCount += 1;
}
}
};
});
The link function provides the scope for this directive. We create a clickCount and a function in the directives "isolate scope"
Additional Functionality
Sometimes, we don't want to create a custom tag, but we want to add custom functionality to any existing tag.
Directives are good for this too.
angular.module('DraggableApp', [])
.directive('myDraggable', ['$document', function($document) {
return {
link: function(scope, element, attr) {
var startX = 0, startY = 0, x = 0, y = 0;
element.css({
position: 'relative',
border: '1px solid red',
backgroundColor: 'lightgrey',
cursor: 'pointer'
});
element.on('mousedown', function(event) {
// Prevent default dragging of selected content
event.preventDefault();
startX = event.pageX - x;
startY = event.pageY - y;
$document.on('mousemove', mousemove);
$document.on('mouseup', mouseup);
});
function mousemove(event) {
y = event.pageY - startY;
x = event.pageX - startX;
element.css({
top: y + 'px',
left: x + 'px'
});
}
function mouseup() {
$document.off('mousemove', mousemove);
$document.off('mouseup', mouseup);
}
}
};
}]);
The examples in these slides are available here
https://github.com/gSchool/angular-curriculum/tree/master/Unit-2/examples/directive-examples
Questions?
Directives
By Tyler Bettilyon
Directives
- 1,352