6

编译服务的 Angular 文档中(从第 412 行开始),有对传递给指令链接函数的 transclude 函数的描述。

相关部分内容如下:

function([scope], cloneLinkingFn, futureParentElement)

其中(第 212 行):

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

  • 默认值:$element.parent()resp。分别$element为 .transclude:'element'transclude:true

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

  • 另请参阅directive.templateNamespace属性。

然而,我看不到重点futureParentElement。它说

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

但是你这样做cloneLinkingFn本身就是这样的:

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

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

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

4

1 回答 1

7

可以通过查看git blamecompile.js来找到答案:添加的提交futureParentElementhttps://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 的<svg-custom-transclude-container><circle cx="2" cy="2" r="1"></circle>行为:

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 内容包装在<svg> ... </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 处理。

于 2015-06-13T17:04:57.970 回答