在不添加新元素的情况下嵌入 AngularJS

Posted

技术标签:

【中文标题】在不添加新元素的情况下嵌入 AngularJS【英文标题】:Transclude in AngularJS without adding new element 【发布时间】:2013-10-25 00:45:26 【问题描述】:

有没有什么方法可以在不添加额外元素的情况下将某些内容转入指令中。

例如

指令:


    scope: 
        someParam: "="
    ,
    link: function(scope, element, attrs)
        //do something
    ,
    transclude: true,
    template:'<div ng-transclude></div>'

源代码:

<div my-directive some-param="somethingFromController">
    my transcluded content: somethingElseFromController
</div>

在这个例子中,一个额外的 div 被添加到标记中。通常这会很好,但我试图在表格中使用这个指令,所以添加一个 div 标签搞砸了。

我还尝试不指定 transcludetemplate 以消除额外的 div 标签,但现在无法找到 somethingElseFromController,因为“transcluded”内容位于隔离范围内。我知道我可以从链接函数中的 attrs 对象获取我的指令的参数,而不是创建一个孤立的范围,但我宁愿避免需要使用 scope.$apply() 评估字符串。

有谁知道如何做到这一点? 谢谢!

【问题讨论】:

somethingElseFromController 打算提供的“嵌入”内容是什么? 可以是任何东西。例如来自控制器的字符串。我只需要我的嵌入内容与控制器在同一范围内。 angular 需要一个元素来“挂起”范围。但是,如果您只是想添加行为,那么正如您所说,您不需要模板。是的,否则,使用父作用域。 好的,谢谢你的信息。我考虑过这样做,但随后我会从标记中丢失标签类型,我将不得不从指令模板中猜测它应该是什么。而且我还会丢失被替换的标记标签上的任何其他属性....哦,好吧,我可能会咬牙切齿并使用 attrs 而不是创建一个孤立的范围 【参考方案1】:

详细说明@rob 的帖子...

Transclusion 要求 Angular 创建一个元素,该元素是指令所在/存在的任何标记的内容的克隆...如果内容是文本,它将把它包装在一个跨度中。

这是因为它有一个 DOM 元素可以在调用 $compile 时应用范围。

所以,基本上 transclude 添加了一个元素,原因与您不能 $compile('plain text here wee') 相同。

现在,您可以执行类似于您尝试使用$interpolate 执行的操作,它允许您将范围应用于字符串中的绑定,例如“blah foo”...。但是因为我真的不确定你想做什么,所以我不能给你一个具体的例子。

【讨论】:

轰隆隆!令人惊讶的是,找到一个简单的答案需要多长时间,但这里的这一点为我解开了它。 “嵌入要求 Angular 创建一个元素,该元素是指令所在/存在的任何标签的内容的克隆……如果内容是文本,它将把它包装在一个跨度中。”谢谢你,先生!【参考方案2】:

这实际上在 Angular 中是可能的。诸如 ng-repeat 之类的指令就是这样做的。以下是你的做法:


    restrict: 'A',
    transclude: true,
    compile: function (tElement, attrs, transclude) 
        return function ($scope) 
            transclude($scope, function (clone) 
                tElement.append(clone);
            );
        ;
    
;

那么这里发生了什么?在链接过程中,我们只是将克隆(我们试图嵌入的元素)附加到指令的元素中。 Angular 会将 $scope 应用到 clone 元素上,这样你就可以在该元素内做所有的角度优点。

【讨论】:

值得注意的是,该解决方案在较新版本的 Angular 中已被弃用。具体来说,使用 transclude 参数传递给编译函数。当前接受的“正确”方法如上所示,除了在链接函数中使用 transclude 参数(传递给链接的第 5 个参数)。【参考方案3】:

@Vakey 回答的是我正在寻找的内容。

但就像今天一样,Angular 文档说:

传递给 compile 函数的 transclude 函数已弃用,例如不知道正确的外部范围。请改用传递给链接函数的 transclude 函数。

所以我改用controller(暂时)及其$transclude 函数,作为$compile documentation 上示例的一部分:

controller: function($scope, $element, $transclude) 
            var transcludedContent, transclusionScope;

            $transclude(function(clone, scope) 
                $element.append(clone);
                transcludedContent = clone;
                transclusionScope = scope;
            );
        ,

【讨论】:

对于 Angular 2,现在称为 Projections,请参阅 ***.com/a/42019804/2012945

以上是关于在不添加新元素的情况下嵌入 AngularJS的主要内容,如果未能解决你的问题,请参考以下文章

如何在不跟踪索引的情况下将元素附加到列表?

如何在不使用 HTML 的情况下向 JLabel 添加换行符

如何在不跟踪索引的情况下将元素附加到列表中?

如何在不重启 Spring Boot 的情况下使用 Spring Security 添加新用户

如何在不使用 &nbsp 的情况下在行内元素之间添加空格 [重复]

如何在不添加新 JObject 键/名称的情况下将 JArray 添加到 JObject 中?