It use to be that AngularJS directives were applied to a single DOM (Document Object Model) node (and its descendants). With AngularJS 1.2, however, you can now apply a directive to a "range" of sibling DOM nodes. To do this, you append "-start" and "-end" to the directive element attributes. I am not yet sure how I would use this feature; but, I wanted to take a quick look at how it works.
View this demo in my JavaScript-Demos project on GitHub.
Imagine that I have a directive attribute, "bn-thing". This would be applied to a single DOM node. If I wanted to apply it to a range of DOM nodes, however, I could alter it such that the first, or "start" DOM node, would have the directive attribute:
bn-thing**-start**
Then, I could add an attribute to the "end" DOM node:
bn-thing**-end**
Notice that I have append "-start" and "-end" to the directive, "bn-thing".
Normally, the compile and link functions receive a jQuery (or JQLite) reference that contains a single DOM node - the one on which the directive is being applied. With these attributes in place, however, both the compile and link functions receive a jQuery (or JQLite) reference that contains a collection of all the DOM nodes in between the "start" and "end" nodes, inclusive.
To explore this change, I created two directives - one that simply "links" the DOM nodes and another that compiles the DOM nodes. The simple one does nothing more than add a class - "item" - to all the DOM nodes in the directive "range." The complex one compiles the DOM, placing the elements inside a new Div container.
<!doctype html>
<html ng-app="Demo">
<head>
<meta charset="utf-8" />
<title>
Using Start/End Directive-Ranges In AngularJS 1.2
</title>
<style type="text/css">
div.container {
border: 1px solid red ;
margin: 16px 0px 16px 0px ;
padding: 0px 16px 0px 16px ;
}
p.item {
border: 1px solid gold ;
}
</style>
</head>
<body ng-controller="AppController">
<h1>
Using Start/End Directive-Ranges In AngularJS 1.2
</h1>
<!-- START: Simple Directive Test. -->
<p bn-simple-start>
Start Simple Directive
</p>
<p>
... content...
</p>
<p bn-simple-end>
End Simple Directive
</p>
<!-- END: Simple Directive Test. -->
<!-- START: Simple Directive Test. -->
<p bn-complex-start>
Start Complex Directive
</p>
<p>
... content...
</p>
<p bn-complex-end>
End Complex Directive
</p>
<!-- END: Simple Directive Test. -->
<!-- Load scripts. -->
<script type="text/javascript" src="../../vendor/jquery/jquery-2.0.3.min.js"></script>
<script type="text/javascript" src="../../vendor/angularjs/angular-1.2.min.js"></script>
<script type="text/javascript">
// Create an application module for our demo.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// I control the root of the application.
app.controller(
"AppController",
function( $scope ) { /* ... */ }
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I simply decorate the elements in the linking phase.
app.directive(
"bnSimple",
function() {
// I bind the UI to the $scope.
function link( $scope, elements, attributes ) {
console.log( "Simple Element(s):" );
console.log( elements );
elements.addClass( "item" );
}
// Return the directive configuration.
return({
link: link
});
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I transclude the set of elements in the directive, wrapping
// them in a container before injecting them back into the DOM.
app.directive(
"bnComplex",
function() {
// Since we are transcluding the "element", there will
// be no rendered DOM elements until the template
// element is cloned and transcluded.
function compile( tElement, tAttributes, transclude ) {
// I bind the UI to the $scope.
function link( $scope, element, attributes ) {
transclude(
$scope,
function( clonedContents ) {
clonedContents.addClass( "item" );
var div = $( "<div />" )
.addClass( "container" )
.append( clonedContents )
.insertAfter( element )
;
}
);
}
return( link );
}
// Return the directive configuration.
return({
compile: compile,
transclude: "element"
});
}
);
</script>
</body>
</html>
When we run the above code, we get the following page output:
As you can see, when using the "-start" and "-end" directive modifiers, the link function is given a collection of DOM nodes instead of a single DOM nodes. Other than that, however, the directives basically work the same way as they did before. Of course, "-start" and "-end" are now special syntax tokens and cannot be used as part of single-point directives (which is a breaking change in AngularJS 1.2). Again, I'm not exactly sure how I would use this kind of a directive "range"; but, it's definitely interesting.
Want to use code from this post? Check out the license.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4