Question

I want to use my directives within other directives. The following example gives so strange results that I had to give up and ask this question. I would like someone to explain me what is going on here:

var app = angular.module('blah', []);

app.directive('one', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<outer>one</outer>'
    };
});

app.directive('two', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<outer>two</outer>'
    };
});

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

HTML:

    <outer>whatever</outer>
    <one></one>
    <two></two>
    <outer>something</outer>

The resulting DOM is:

    <div ng-transclude=""></div>
    <outer></outer>
    <two></two>
    <outer>something</outer> 

JSFiddle: http://jsfiddle.net/WPpUL/

Is it a bug?

EDIT:

Expected output DOM:

    <div ng-transclude>whatever</div>
    <div ng-transclude>one</div>
    <div ng-transclude>two</div>
    <div ng-transclude>something</div>
Was it helpful?

Solution

Instead of using replace we'll do it manually- this seems to keep angular happy and gets you what you need.

1) Set replace: false instead of true in One and Two. (making angular happy)

2) Manually replace the html using this link function to One and Two:

link: function(scope, element, attrs) {
    element.replaceWith(element.html());
}

This will result in:

<div ng-transclude=""><b class="ng-scope">whatever</b></div>
<div ng-transclude=""><b class="ng-scope">one</b></div>
<div ng-transclude=""><b class="ng-scope">two</b></div>
<div ng-transclude=""><b class="ng-scope">something</b></div> 

The text nodes have been surrounded by B tags to get rid of automatically generated SPANs.

Here's the updated fiddle: http://jsfiddle.net/WPpUL/7/

OTHER TIPS

Wrap template with a root element will fix the problem

template: '<div><outer>one</outer></div>'
template: '<div><outer>two</outer></div>'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top