Pick up Custom Directives in AngularJS
Introduction:
First of all thank you to all of you for reading this
article. I wanted to write technical article from last 2 years but not able to
do so. But any way, this is my first technical article.
I have done deep research on custom directives in AngularJS
and thought this is the right time to give back to technical community while
contributing my bit.
What is Custom
Directive in AngularJS?
First of all let me tell you what is directive in AngularJS?
As
a high level, directives are indicators on a DOM element (such as an attribute,
element name, comment or CSS class) that tell AngularJS's HTML compiler
to attach a specified behavior to that DOM element (e.g. via event listeners),
or even to transform the DOM element and its children.
“ng-Bind, ng-Model, ng-app, ng-show, ng-if and ng-controller
etc are the built in directive in the AngularJS.”
There
are so many cases where these built in directives does not fit into the
requirement, so angular gives you flexibility to create your own custom
directives.
The
custom directive gets executed when Angular bootstraps your application, the HTML compiler traverses the DOM matching directives against
the DOM elements.
Custom
directive should be written in camelCase and then angular will normalize this
into different format.
Ex:
sampleDirective
This
can be written in HTML page like:
<sample_directive></ sample_directive
>
<sample-directive></
sample-directive >
<sample:directive></
sample:directive >
Best
Practice: Prefer
using the dash-delimited format (e.g. ng-bind for ngBind). If you want to use an HTML validating tool,
you can instead use the data-prefixed version (e.g. data-ng-bind for ngBind). The
other forms shown above are accepted for legacy reasons but this is advisable
to avoid them.
Directive types:
There
are four types of directives based on element names, attributes, class names,
as well as comments.
Create
Custom Directive:
The
custom directives are registered on modules. To register a directive, we have
to use the module.directive API. module.directive takes the camleCase directive
name followed by a factory function. This factory function should return an
object with the different options to tell $compile how the directive should
behave when matched.
The
factory function is invoked only once when the compiler matches the directive
for the first time. Any initialization work should be performed here.
Best
Practice:
In order to avoid collisions with some future standard, it's best to prefix
your own directive names. For instance, if you created a <carousel>
directive, it would be problematic if HTML7 introduced the same element. A two
or three letter prefix (e.g. devCarousel) works well. Similarly, do not prefix
your own directives with ng or they might conflict with directives included in
a future version of Angular.
Let’s
create some example for the custom directive.
I
am using Visual studio .Net IDE to work on the example you can use own if
required.
Step 1: Open a
visual studio and create a new project as web application.
Step 2: Select
any type of application for this example or choose as per your requirement.
Step 3: Install
the latest AngularJS from nugget packages using below screen.
Step 4: Click on
Install button for installing the package.
Step 5: After
application gets ready, create a new
JavaScript file “$\Scripts\CustomDirective.js” for custom directive code.
JavaScript Code:
/// <reference
path="angular.js" />
var sampleApp = angular.module("SampleApp", []);
sampleApp.directive('sampleDirective', function () {
return {
template: '<div><b>Hi there!! this is a first custom
directive!!!!</b></div>',
restrict: 'E'
};
});
Step 6: Create new Html page
“CustomDirective.html” for html code.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Custom Directive</title>
<link href="Content/bootstrap.css" rel="stylesheet" />
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/CustomDirective.js"></script>
</head>
<body ng-app="SampleApp">
<div>
<sample-directive></sample-directive>
</div>
</body>
</html>
Output should be look like below:
Finally your first directive is readyJ
So
the restrict option in the above custom directive is E but you can use
following other options:
- 'A' - only matches attribute
name
- 'E' - only matches element
name
- 'C' - only matches class name
These
restrictions can all be combined as needed:
- 'AEC' - matches either
attribute or element or class name
When should I use an
attribute versus an element? Use an element when you are
creating a component that is in control of the template. The common case for
this is when you are creating a Domain-Specific Language for parts of your
template. Use an attribute when you are decorating an existing element with new
functionality.
If the size of the
template is too big it is advisable to create a new html file and use “templateUrl”
for loading the html code.
Ex:
Change the custom
directive code like below:
sampleApp.directive('sampleDirective', function () {
return {
templateUrl: 'sampleApp.html,
restrict: 'E'
};
});
Now, the time to use the ng-controller in the customer
directive. Below is the sample implementation of the directive with controller.
Custom directive with
Controller:
JavaScript Code:
/// <reference
path="angular.js" />
var sampleApp = angular.module("SampleApp", []);
sampleApp.controller('StudentController', function ($scope) {
$scope.student = {};
$scope.student.name = "Abhay Saxena";
$scope.student.Age = 35;
});
sampleApp.directive('student', function () { // this is the another way of writing
directive function.
var directive = {};
directive.restrict = 'E';
directive.scope = false;
directive.template = "Student: <b>{{student.name}}</b> , Age:
<b>{{student.Age}}</b>";
return directive;
});
HTML Code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Custom Directive</title>
<link href="Content/bootstrap.css" rel="stylesheet" />
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/CustomDirective.js"></script>
</head>
<body ng-app="SampleApp">
<div ng-controller="StudentController">
<student></student>
</div>
</body>
</html>
Output should look like:
Now, the turn for Isolating the Scope of a Directive:
The
above directive is great, but it has a fatal error. We can only use it once
within a given scope.
In
its current implementation, we'd need to create a different controller each
time in order to re-use such a directive. Let’s see the below example.
JavaScript
Code:
/// <reference
path="angular.js" />
var sampleApp = angular.module("SampleApp", []);
sampleApp.controller('StudentController', function ($scope) {
$scope.student = {};
$scope.student.name = "Abhay Saxena";
$scope.student.Age = 35;
});
sampleApp.controller('NewStudentController', function ($scope) {
$scope.student = {};
$scope.student.name = "Sanjay Saxena";
$scope.student.Age = 30;
});
sampleApp.directive('student', function () {
var directive = {};
directive.restrict = 'E';
directive.scope = false;
directive.template = "Student: <b>{{student.name}}</b> , Age:
<b>{{student.Age}}</b>";
return directive;
});
HTML Code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Custom Directive</title>
<link href="Content/bootstrap.css" rel="stylesheet" />
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/CustomDirective.js"></script>
</head>
<body ng-app="SampleApp">
<div ng-controller="StudentController">
<student></student>
</div>
<div ng-controller="NewStudentController">
<student></student>
</div>
</body>
</html>
Output:
So
to avoid creating a new controller each time, we need to isolate the scope for
the directive implementation.
JavaScript Code:
/// <reference
path="angular.js" />
var sampleApp = angular.module("SampleApp", []);
sampleApp.controller('StudentController', ['$scope',function ($scope) {
$scope.Abhay = { name: 'Abhay Saxena', Age:
35 };
$scope.Sanjay = { name: 'Sanjay Singh', Age:
38 };
}])
sampleApp.directive('student', function () {
var directive = {};
directive.restrict = 'E';
directive.scope= {studentInfo:'=information'}
directive.template = "Student: <b>{{studentInfo.name}}</b> ,
Age: <b>{{studentInfo.Age}}</b>";
return directive;
});
HTML Code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Custom Directive</title>
<link href="Content/bootstrap.css" rel="stylesheet" />
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/CustomDirective.js"></script>
</head>
<body ng-app="SampleApp">
<div ng-controller="StudentController">
<student information="Abhay"></student>
<hr>
<student information="Sanjay"></student>
</div>
</body>
</html>
Output:
Ref: https://docs.AngularJS.org/guide/directive

No comments:
Post a Comment