Angular Custom Directive - gpawade/gpawade.github.io GitHub Wiki

In this sample we are creating custom directive and how to implement it in angular app.

Custom directives are used to extend the functionality of HTML. Angular support built in directives like ngModel, ngBind, ngClass etc.

Angular js provides support to crete the custom directives for

  • Element - directive activates when matching element.
  • Attribute - directive activate when matching attributes.
  • CSS - directive activate when matching css style.
  • Comment - directive activate when matching comment.
var app = angular.module('myapp',[]);

app.directive('myCustomDirective', function(){
	
	var directive = {};
	
	// restrict - E - signifies that directive is element directive.
	directive.restrict = 'E';
	
	//template replaces the complete element with its text.
	directive.template = '<p>test from directive</p>';
	
	//scope is used to distinguish each person element based on criteria.
	directive.scope = {
		person : "=name"
	}
	
	//compile is called during application initialization. AngularJS calls it once when html page is loaded.
	directive.compile = function(element, attributes) {
		element.css("border", "1px solid #cccccc");
		
		//linkFunction is linked with each element with scope to get the element specific data.
		var linkFunction = function($scope, element, attributes) {
			element.html("Person: <b>"+$scope.person.name +"</b><br/>");
			element.css("background-color", "#ff00ff");
		}
		return linkFunction;
	}
	
	return directive;

});

Directive Option

Restrict

Restrict option is used to specify how a directive can be invoked on page.

There are four valid option for restrict.

  • 'A' - directive is attribute directive. e.g. <span my-custom-directive></span>
  • 'E' - directive is element directive. e.g. <my-custom-directive></my-custom-directive>
  • 'C' - directive is CSS style direct#ive. e.g. <span class="my-custom-directive"></span>
  • 'M' - directive is comment directive. e.g. <!-- directive:my-custom-directive -->

Note - the restrict option can specify multiple options, as well.

   restrict : 'EA'

Template

We can pass inline template to directive using template option where we can specify the HTML that will be appended(or replaced).

	template : "<p>html template</p>"

Template URL

If we want to load the template over ajax, we can specify the templateurl options.

	templateurl : '/path/to/template/html/file'

Compile

The compile() function is called once for each occurrence of the directive in the HTML page. The compile() function can then do any one-time configuration needed of the element containing the directive. The compile() function finishes by returning the link() function.

compile : function(element, attribute){
	//do one time configuration here
	
	var linkFun = function($scope, element, attribute){
		// bind element to data in $scope	
	}
	return linkFun;
}

Link

Use the link option to register DOM listeners as well as update/manipulate the DOM.

	link : function(scope, element, attrs, controller, transcludeFn){ //post link
		// scope - is an angular scope object
		//attrs is a hash object with key-value pairs of normalized attribute names and their corresponding attribute values.
		//controller is the directive's required controller instance(s) or its own controller (if any). The exact value depends on the directive's require property.
		//transcludeFn is a transclude linking function pre-bound to the correct transclusion scope.	
	}
	// OR
	// link : {
	// 	pre : function (scope, element, attrs, controller){
	// 	},
	// 	post : function ( scope, element, attrs, controller){
	// 	  // simillar to 	
	// 	}
	// }

Transclude

You can pass in models to a directive using the isolate scope, but sometimes it's desirable to be able to pass in an entire template rather than a string or an object.

transclude: true,
template : 'header text <div  ng-transclude></div>Footer text'

Usage-

<my-customdirective>Check out the contents, {{name}}!</my-customdirective>

transclude makes the contents of a directive with this option have access to the scope outside of the directive rather than inside.

Controller

Use controller when you want to expose an API to other directives, otherwise use link.

controller : ['$scope',function(){
	// code goes here	
}]

Scope

Issolated scope is created in directive using scope property. Type -

  • @ - used to pass the string value to directive. This local scope property use when you want to one way binding between parent controller to directive. When parent controller value change then directive value will be change, but vice versa not allowed.
    scope : {
		name : "@",     // attribute name & scope name are equal
		param : "@attrname" // attribute name & scope are not equal
    <my-directive name = "{{person.name}}"  attrname = "{{person.attrname}}" >
  • = - used to pass two way binding between parent scope with directive.
    scope : {
		person : "="
    <my-directive name = "person"  >
  • & - Allows an external function to be passed into the directive and invoked
⚠️ **GitHub.com Fallback** ⚠️