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

2

95

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

Uzzia answered 19/3, 2014 at 6:11 Comment(0)
J
35

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

Jordanson answered 20/2, 2016 at 4:41 Comment(2)
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?Inch
@devios I need such thing for my mdl components but currently using remove-host workaround #34280975 if you find out about activating replace: true in A2 let us know.Cowhide
T
191

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.

Tribe answered 19/3, 2014 at 6:30 Comment(3)
This is a wonderfully simple explanation. And thanks a bunch for clarifying the transclusion too.Uzzia
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?Viscounty
@Viscounty replace has been deprecated since AngularJS v1.3 (link).Unlive
J
35

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

Jordanson answered 20/2, 2016 at 4:41 Comment(2)
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?Inch
@devios I need such thing for my mdl components but currently using remove-host workaround #34280975 if you find out about activating replace: true in A2 let us know.Cowhide

© 2022 - 2024 — McMap. All rights reserved.