【问题标题】:In the transclude function of a directive link function, how is "futureParentElement" used?在指令链接函数的transclude函数中,“futureParentElement”如何使用?
【发布时间】:2015-06-09 14:31:11
【问题描述】:

angular documentation for the compile service (starting at line 412) 中有一个transclude 函数的描述,它被传递到指令的链接函数中。

相关部分内容如下:

function([scope], cloneLinkingFn, futureParentElement)

其中(第 212 行):

futureParentElement:定义cloneLinkingFn 将向其添加克隆元素的父级。

  • 默认:$element.parent() 对应。 $element 分别代表 transclude:'element'transclude:true.

  • 仅在允许包含非 html 元素(例如 SVG 元素)的transcludes 中需要 当cloneLinkinFn 被传递时, 因为当这些元素在其常用容器之外定义时(例如<svg>),需要以特殊方式创建和克隆。

  • 另请参阅directive.templateNamespace 属性。

但是,我看不到futureParentElement 的意义。它说

定义 cloneLinkingFn 将向其添加克隆元素的父级。

但是你在 cloneLinkingFn 本身中这样做是这样的:

transclude(scope, function (clone) {
    some_element.append(clone);
});

如果不首先定义克隆函数,就不能使用 transclude 函数。

futureParentElement 的正确用法/用途是什么?

【问题讨论】:

    标签: angularjs angularjs-directive transclusion angularjs-ng-transclude


    【解决方案1】:

    可以通过查看git blame of compile.js 找到答案:添加futureParentElement 的提交是https://github.com/angular/angular.js/commit/ffbd276d6def6ff35bfdb30553346e985f4a0de6

    在提交中有一个测试指令svgCustomTranscludeContainer

    directive('svgCustomTranscludeContainer', function() {
      return {
        template: '<svg width="400" height="400"></svg>',
        transclude: true,
        link: function(scope, element, attr, ctrls, $transclude) {
          var futureParent = element.children().eq(0);
          $transclude(function(clone) {
            futureParent.append(clone);
          }, futureParent);
        }
      };
    });
    

    通过测试编译 html &lt;svg-custom-transclude-container&gt;&lt;circle cx="2" cy="2" r="1"&gt;&lt;/circle&gt; 的行为:

    it('should handle directives with templates that manually add the transclude further down', inject(function() {
      element = jqLite('<div><svg-custom-transclude-container>' +
          '<circle cx="2" cy="2" r="1"></circle></svg-custom-transclude-container>' +
          '</div>');
      $compile(element.contents())($rootScope);
      document.body.appendChild(element[0]);
    
      var circle = element.find('circle');
      assertIsValidSvgCircle(circle[0]);
    }));
    

    因此,如果您使用指令创建 SVG 图像,该指令的模板将转置的 SVG 内容包装在 &lt;svg&gt; ... &lt;/svg&gt; 标签中,那么如果您不通过,该 SVG 图像将无效(根据某种定义)正确的futureParentElement$transclude

    除了源代码中的测试之外,为了了解无效的实际含义,我根据单元测试中的指令创建了 2 个指令,并使用它们尝试创建带有部分圆形的 SVG 图像。一个使用futureParentElement

    <div><svg-custom-transclude-container-with-future><circle cx="1" cy="2" r="20"></circle></svg-custom-transclude-container></div>
    

    一个相同但不同的:

    <div><svg-custom-transclude-container-without-future><circle cx="2" cy="2" r="20"></circle></svg-custom-transclude-container></div>
    

    http://plnkr.co/edit/meRZylSgNWXhBVqP1Pa7?p=preview 可以看出,带有futureParentElement 的那个显示了部分圆圈,而没有那个没有。 DOM 的结构看起来相同。然而,Chrome 似乎报告第二个 circle 元素不是 SVG 节点,而是纯 HTML 节点。

    因此,无论futureParentElement 在幕后实际做了什么,它似乎确保了嵌入的 SVG 内容最终被浏览器作为 SVG 处理。

    【讨论】:

    • 所以和html内容无关吧?
    • @krave 我相信是这样的:“只需要允许包含非 html 元素的嵌入”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 2017-06-29
    • 2014-03-11
    相关资源
    最近更新 更多