How to use the 'replace' feature for custom AngularJS directives?

105,483

Solution 1

replace:true is Deprecated

From the Docs:

replace ([DEPRECATED!], will be removed in next major release - i.e. v2.0)

specify what the template should replace. Defaults to false.

  • true - the template will replace the directive's element.
  • false - the template will replace the contents of the directive's element.

-- AngularJS Comprehensive Directive API

From GitHub:

Caitp-- It's deprecated because there are known, very silly problems with replace: true, a number of which can't really be fixed in a reasonable fashion. If you're careful and avoid these problems, then more power to you, but for the benefit of new users, it's easier to just tell them "this will give you a headache, don't do it".

-- AngularJS Issue #7636


Update

Note: replace: true is deprecated and not recommended to use, mainly due to the issues listed here. It has been completely removed in the new Angular.

Issues with replace: true

For more information, see

Solution 2

When you have replace: true you get the following piece of DOM:

<div ng-controller="Ctrl" class="ng-scope">
    <div class="ng-binding">hello</div>
</div>

whereas, with replace: false you get this:

<div ng-controller="Ctrl" class="ng-scope">
    <my-dir>
        <div class="ng-binding">hello</div>
    </my-dir>
</div>

So the replace property in directives refer to whether the element to which the directive is being applied (<my-dir> in that case) should remain (replace: false) and the directive's template should be appended as its child,

OR

the element to which the directive is being applied should be replaced (replace: true) by the directive's template.

In both cases the element's (to which the directive is being applied) children will be lost. If you wanted to perserve the element's original content/children you would have to translude it. The following directive would do it:

.directive('myDir', function() {
    return {
        restrict: 'E',
        replace: false,
        transclude: true,
        template: '<div>{{title}}<div ng-transclude></div></div>'
    };
});

In that case if in the directive's template you have an element (or elements) with attribute ng-transclude, its content will be replaced by the element's (to which the directive is being applied) original content.

See example of translusion http://plnkr.co/edit/2DJQydBjgwj9vExLn3Ik?p=preview

See this to read more about translusion.

Share:
105,483
Kaya Toast
Author by

Kaya Toast

Making progress on coding, one step at a time.

Updated on February 25, 2020

Comments

  • Kaya Toast
    Kaya Toast over 4 years

    Why does replace=true or replace=false not have any impact in the code below?

    Why isn't the "some existing content" being displayed when replace=false?

    Or putting it more humbly, can you kindly explain what is the replace=true/false feature in directives and how to use it?

    Example

    JS/Angular:

    <script>
        angular.module('scopes', [])
              .controller('Ctrl', function($scope) {
                    $scope.title = "hello";
    
              })
              .directive('myDir', function() {
                return {
                  restrict: 'E',
                  replace: true,
                  template: '<div>{{title}}</div>'
                };
          });
    </script>
    

    HTML:

    <div ng-controller="Ctrl">
        <my-dir><h3>some existing content</h3></my-dir>
    </div>
    

    See it in Plunker here:

    http://plnkr.co/edit/4ywZGwfsKHLAoGL38vvW?p=preview

  • Kaya Toast
    Kaya Toast over 10 years
    This is a wonderfully simple explanation. And thanks a bunch for clarifying the transclusion too.
  • Trindaz
    Trindaz about 9 years
    More importantly, why isn't it explained at docs.angularjs.org/guide/directive and why doesn't this answer link to a definitive answer on the topic?
  • Tonči D.
    Tonči D. over 8 years
    @Trindaz replace has been deprecated since AngularJS v1.3 (link).
  • devios1
    devios1 over 8 years
    I keep reading that this is supposed to be unofficially supported in Angular 2, but I can't figure out how to activate it. Can someone tell me what the syntax is?
  • angularrocks.com
    angularrocks.com over 8 years
    @devios I need such thing for my mdl components but currently using remove-host workaround stackoverflow.com/questions/34280475/… if you find out about activating replace: true in A2 let us know.