嵌套Angular指令的奇怪行为

时间:2013-11-15 14:52:06

标签: javascript angularjs angularjs-directive

我想在其他指令中使用我的指令。以下示例给出了如此奇怪的结果,我不得不放弃并提出这个问题。我想有人向我解释一下这里发生了什么:

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>

生成的DOM是:

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

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

这是一个错误吗?

修改

预期输出DOM:

    <div ng-transclude>whatever</div>
    <div ng-transclude>one</div>
    <div ng-transclude>two</div>
    <div ng-transclude>something</div>

2 个答案:

答案 0 :(得分:1)

使用根元素包装模板将解决问题

template: '<div><outer>one</outer></div>'
template: '<div><outer>two</outer></div>'

答案 1 :(得分:1)

而不是使用replace我们会手动执行 - 这似乎可以保持角度快乐并为您提供所需的信息。

1)在One和Two中设置replace: false而不是true。 (使角度快乐)

2)使用此链接功能手动将html替换为One和Two:

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

这将导致:

<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> 

文本节点已被B标记包围,以摆脱automatically generated SPANs

这是更新的小提琴:http://jsfiddle.net/WPpUL/7/