The other day, my friend Sam Lin pointed out that my use of the transclude() function in a JavaScript demo had been deprecated in AngularJS 1.2. After looking at the documentation, I was quite pleased to find out that he was right. While the change appears fairly cosmetic, I think it makes the directive configuration much more straightforward. Now, rather than having to define the compile() function just to get a reference to transclude(), the transclue() function is passed directly into the link() function.
View this demo in my JavaScript-Demos project on GitHub.
Before AngularJS 1.2, if you wanted a directive to transclude its element, you had to define the compile() function so that you could get a reference to the transclude() function. This was because the compile() function was the only place the transclude() function was made available (outside of explicit calls to $compile). As such, you ended up with a number of directives that had a non-functional - but required - compile() wrapper.
With AngularJS 1.2, however, this superfluos compile wrapper is no longer necessary; if your directive configuration defines transclusion, the transclusion function is now passed directly into the link() function as the fifth (5th) argument, after the optional controller(s) argument.
To see this in action, I created a simple demo that uses both the old [deprecated] and the new approaches to transclude() function injection:
<!doctype html>
<html ng-app="Demo">
<head>
<meta charset="utf-8" />
<title>
Transclude Function Passed To Link Function In AngularJS 1.2
</title>
</head>
<body>
<h1>
Transclude Function Passed To Link Function In AngularJS 1.2
</h1>
<!-- Will demonstrate old-school transclude configuration. -->
<p bn-old-transclude>
Old Transclude!
</p>
<!-- Will demonstrate new, easier transclude configuration. -->
<p bn-new-transclude>
New Transclude!
</p>
<!-- 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.4.min.js"></script>
<script type="text/javascript">
// Create an application module for our demo.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// In the old-school transclude configuration, you NEEDED to
// define the compile() method just to get a reference to the
// transclude function. Notice that the compile() isn't
// actually doing anything - it's just there so that the
// "transclude" argument can be defined.
app.directive(
"bnOldTransclude",
function() {
function compile( tElement, tAttributes, transclude ) {
// At this point, the "element" is the COMMENT
// that has been injected into the DOM as an anchor
// for the subsequent transclusion.
function link( $scope, element, attributes ) {
transclude(
$scope,
function( clone ) {
clone.css( "border", "2px solid pink" );
element.after( clone );
}
);
}
return( link );
}
// Return the directive configuration.
return({
compile: compile,
restrict: "A",
transclude: "element"
});
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// In the new transclude configuration, you no longer need the
// COMPILE function _just_ to define the transclude function;
// the transclude function is now passed as an optional
// argument directly to the link() function.
// --
// NOTE: I defined the "controller" argument since the
// transclude function is after it. However, since I am not
// actually "require"ing any controllers, I am naming it "null."
app.directive(
"bnNewTransclude",
function() {
// At this point, the "element" is the COMMENT that
// has been injected into the DOM as an anchor for
// the subsequent transclusion.
function link( $scope, element, attributes, nullController, transclude ) {
transclude(
$scope,
function( clone ) {
clone.css( "border", "2px solid gold" );
element.after( clone );
}
);
}
// Return the directive configuration.
return({
link: link,
restrict: "A",
transclude: "element"
});
}
);
</script>
</body>
</html>
Both of the above directives do the exact same thing; only, the second one doesn't use or require the compile() function in order to access the transclude() function. This is a fairly cosmetic change - but it is certainly a much cleaner and much more convenient approach. I'm really glad they went in this direction.
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