<!DOCTYPE html> <html> <head> <script src="angular.js"></script> <script src="script.js"></script> <style> .spanBackground { background-color: yellow; } .divFrame { border-width: 1px; border-style: solid; } .logTextArea { width: 400px; height: 200px; } </style> </head> <body ng-app="mainModule"> <div ng-controller="mainController"> <h3>1. Only the inner HTML of the DOM node is replaced</h3> <div ngh-no-replace-dir> <strong>This content will be replaced</strong> <div> This one will be replaced too </div> </div> <br /> <h3>2. The element of the DOM node is replaced and the attributes are merged</h3> <span ngh-replace-dir my-span-attribute my-common-attribute="span value" style="font-weight: bold; color: blue;" class="spanBackground"> <strong>This content will be replaced</strong><br /> <em>This one will be replaced too</em> </span> <br /> This is the DOM node after the compilation:<br /> <textarea class="logTextArea">{{nghReplaceDirLog}}</textarea> </div> </body> </html>
angular.module("mainModule", []) .controller("mainController", function ($scope) { $scope.myScopeVar = "the scope variable value"; $scope.nghReplaceDirLog = ""; }) // 1. Directive that replaces only the inner HTML of the DOM node .directive("nghNoReplaceDir", function () { return { replace: false, template: 'This is <strong>nghNoReplaceDir</strong> directive printing <em>{{myScopeVar}}</em>' }; }) // 2. Directive that replaces the element of the DOM node // and merges the attributes of the original element // with those of the template. .directive("nghReplaceDir", function () { return { replace: true, template: '<div my-div-attribute my-common-attribute="div value" style="font-size: 18px;" class="divFrame">\n\n' + 'This is <strong>nghReplaceDir</strong> directive printing <em>{{myScopeVar}}</em>\n\n' + '</div>', link: function (scope, element, attrs) { // Log the compiled HTML element scope.nghReplaceDirLog = element[0].outerHTML; } }; });



We can decide if our custom directive with a template has to replace the inner HTML of a DOM node or also the element of the node by using the replace property of the directive's definition object.

Point 1 of the example shows the default behavior of a custom directive with a template in the definition object. Here the replace property is specified with the false value, but if it wasn't specified at all in the definition object, that would've been its default value. In this case only the inner HTML of the DOM node where the directive appears is replaced with the template.

Point 2 shows what happens when replace is true. The original span element is replaced with the div element of the template and all the attributes of the original DOM node are merged with those in the template's root node: all the attributes of both the original node and the template appear in the final DOM node and for each attribute the concatenation of its original and its template value will be its final value. In the text area you can see the final DOM node after AngularJS has compiled it (we use the link function because we're sure that at that stage the full HTML template has been compiled). As you can see, you must be very careful on the kind of merged content you might expect as it might not be exactly the merging you would think of.

NOTE: when replace is true, the template must contain a DOM subtree with a single root node otherwise AngularJS will throw an error because the template's DOM cannot reliably replace the original DOM node element.