在指令链接函数的transclude函数中,如何使用"futureParentElement"?

m0m*_*eni 5 angularjs transclusion angularjs-directive angularjs-ng-transclude

编译服务角度文档中(从第412行开始),有一个transclude函数的描述,该函数被传递到指令的链接函数中.

相关部分如下:

function([scope], cloneLinkingFn, futureParentElement)
Run Code Online (Sandbox Code Playgroud)

其中(第212行):

futureParentElement:定义cloneLinkingFn将添加克隆元素的父级.

  • 默认值:$element.parent()resp.$element对于transclude:'element'resp.transclude:true.

  • 只有在允许包含非html元素(例如SVG元素)的transcludes和cloneLinkinFn传递时才需要,因为这些元素需要在它们通常的容器之外定义时以特殊方式创建和克隆(例如<svg>).

  • 另请参阅directive.templateNamespace酒店.

futureParentElement然而,我没有看到重点.它说

定义cloneLinkingFn将添加克隆元素的父级.

但你这样做cloneLinkingFn就像这样:

transclude(scope, function (clone) {
    some_element.append(clone);
});
Run Code Online (Sandbox Code Playgroud)

如果不首先定义克隆功能,则无法使用transclude函数.

适当的用途/用途是futureParentElement什么?

Mic*_*mza 6

通过查看git责备compile.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);
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

通过测试编译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]);
}));
Run Code Online (Sandbox Code Playgroud)

所以看起来,如果你正在创建一个指令,其模板包裹在transcluded SVG内容的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>
Run Code Online (Sandbox Code Playgroud)

和一个相同但不相同的:

<div><svg-custom-transclude-container-without-future><circle cx="2" cy="2" r="20"></circle></svg-custom-transclude-container></div>
Run Code Online (Sandbox Code Playgroud)

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

因此无论futureParentElement实际上是什么,它似乎确保转换的SVG内容最终被浏览器作为SVG处理.