This is the best way I’ve found to create an Angular.js directive that’s restricted to a specific HTML element or tag.
Angular.js Example
First, here’s a quick code sample of the approach I use. An explanation can be found below.
JavaScript
/**
* Main Application Definition
*/
var ngApp = angular.module( "ngApp", []);
/**
* Relative Anchors
*/
ngApp.directive( 'relativeHref', [ '$location', '$log', function( $location, $log ) {
var link = function( scope, element, attrs ) {
// Verify this directive has been used with a valid HTML element
if ( element[ 0 ].tagName !== "A" ) {
$log.warn( '[relative-href] directives are only allowed for <a> tags.' );
return;
}
// Directive logic...
var host = $location.protocol() + '//' + $location.host();
var href = attrs.relativeHref.replace(host, '');
attrs.$set( 'href', href );
};
return {
link: link,
restrict: 'A'
};
} ] );
HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="mainApp">
<a relative-href="https://plnkr.co/edit/">Relative Plunker Edit Link</a>
<p relative-href="https://plnkr.co/edit/">Relative Link Not Allowed for Paragraphs...</p>
</body>
</html>
Explanation
There’s no directive configuration option in Angular.js to do this, but I recommend adding the restrict: 'A'
to your directives config so that it only matches an attribute name. Once we have that in place the key aspect that makes this happen is this line:
if ( element[ 0 ].tagName !== "A" ) {
Which basically checks the HTML element and provides a block if it’s not an anchor. I like to combine this with the $log
service built-in to angular, which is basically a mirror of the browsers console
object with added benefits. Using the $log.warn()
method I throw a warning to the browser console when an error case occurs for easier debugging.
If you know of a better way please do share it!