Skip to content

AngularJS: Overridable directive templates

2014 December 18
by Alec

Sometimes it’s nice to define a default template for a directive, while also allowing the template to be overridden. This isn’t a built-in feature with Angular: if you specify a template it will always be rendered, and transcluded scopes don’t by default have access to the directive’s scope [1].

The key piece of code (as usual) is in the link function:

transcludeFn(scope, function cloneFn(cElement) {
  if (cElement.length) {
    element.empty();
    element.append(cElement);
  }
});

Here, we’re utilizing the transclude function provided by angular: basically, the result of calling $compile on a new sibling scope to the directive’s scope. However, we pass in the directive’s scope so that the transcluded content has access to whatever we define on it. Then, if any content is inside this directive (represented by cElement, an array of zero or more jqLite elements), replace the default template with the transcluded HTML. VoilĂ !

Edit (Jan 15, 2015): This is the first case I have come across where it may be appropriate to use the scope.$parent attribute within the transcluded (overriding) template. I can’t think of any clean way of accessing the data above the directive otherwise, and the accessible scope attributes should be easily seen (and maintained) in the template file html.

[1] More information here: http://blog.omkarpatil.com/2012/11/transclude-in-angularjs.html

Comments are closed.