传递给链接函数的第二个参数的函数目的是什么?

3

我刚刚发现了以下代码:

var tooltipLinker = $compile(template);
tooltip = tooltipLinker(tooltipLinkedScope, function(tooltip) {
    if (appendToBody) {
        $document.find('body').append(tooltip);
    } else {
        element.after(tooltip);
    }
});

我的问题是在angular框架中,作为链接函数第二个参数传递的函数的目的是什么?我不是在问回调函数的目的。
文档中说$compile返回:
function(scope, cloneAttachFn=, options=)   

所以第二个参数函数似乎是cloneAttachFn。现在我想知道它是否与transcluded函数中的cloneAttachFn具有相同的目的?


你可以执行 console.log(tooltipLinker) 并显示输出吗?然后我们可以从输出中解释它正在做什么。 - 4castle
@4castle,tooltipLinker是一个链接函数,如angular文档所解释的那样。 - Max Koretskyi
1个回答

1
这个函数允许您访问绑定视图并复制模板。它还允许您将先前克隆的元素放置在任何位置。
与传统方式的区别在于:
var tooltipLinker = $compile(template);
var tooltip = tooltipLinker(tooltipLinkedScope);

提示框是对原始元素的引用,而不是克隆。

angular.module('app', [])
  .directive('clone', function($compile) {
    return {
      restrict: 'E',
      link: function($scope, $element) {
        $scope.value = 10;
        var elem = angular.element('<div>{{value}}</div>');
        var compiled = $compile(elem)($scope);
        console.log('elem === compiled', elem === compiled);
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <clone></clone>
</div>

另一方面,当您提供一个克隆附加函数时,该元素始终是原始元素的克隆。

angular.module('app', [])
  .directive('clone', function($compile) {
    return {
      restrict: 'E',
      link: function($scope, $element) {
        $scope.value = 10;
        var e;
        var elem = angular.element('<div>{{value}}</div>');
        var compiled = $compile(elem)($scope, function(cloned, scope) {
          e = cloned;
        });
        console.log('elem === compiled', elem === compiled);
        console.log('elem === callback element', elem === e);
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <clone></clone>
</div>

在第一种情况下,原始元素已编译并准备好放置在DOM中,在第二种情况下,原始元素已编译,但结果可在克隆中使用。
如果您在第二种情况下console.log元素,则会发现仍然存在插值符号。您必须将克隆放置在DOM中。
该函数的目的是告诉Angular如何处理模板引用,直接链接它或先制作一个克隆体,然后链接克隆体。

你会看到它仍然带有插值符号 - 是的,那么这个什么时候会被链接起来? - Max Koretskyi
@Maximus 简短回答是不会的。这就是为什么他们给你一个克隆的原因。你仍然可以将此元素绑定到不同的作用域或进行一些修改并重新编译它。第一种情况会永久修改蓝图,第二种情况会保留蓝图,以便您以后仍然可以使用它。 - devconcept
我真的不太明白...如果我只是将它插入到DOM中,并且它上面有插值符号-这样做的目的是什么?我希望它与某个作用域关联(绑定)。 - Max Koretskyi
@Maximus 在第一种情况下,您可以将原始元素和编译后的元素插入DOM中,因为它们是相同的。在第二种情况下,您只能附加克隆而不是原始元素。请注意,我在调用$compile之前创建一个元素,而不是使用$compile('<div></div>')。您不必担心这个问题,因为调用链接函数(var result = $compile(template)(...))的结果始终是您想要使用的引用。 - devconcept
只是为了让大家在同一个页面上:var plainElem = angular.element('<div>{{value}}</div>'); - 这是普通的DOM元素,var lnFn = $compile(elem) - 链接函数,var linkedElem = $compile(elem)($scope) - 已链接的元素,$compile(elem)($scope, function(cloned, scope) { e = cloned; }); - cloned 是普通的DOM元素。这些正确吗? - Max Koretskyi
不对。cloned 不是一个普通的 DOM 元素,而是从 elem 克隆出来的链接元素。该函数的目的是告诉 Angular 如何处理 elem 引用,直接链接它或先克隆一个副本再链接副本。为什么这很有用?这取决于你想要对 elem 做什么,通常你不需要克隆元素,因为你只链接一次。还要记住,在这里 var ref = $compile(elem)($scope, function(cloned, scope) { })ref === cloned 而不是通常的 ref === elem - devconcept

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接