AngularJS:指令控制器中的$ transclude local和链接函数中的transclude参数之间有区别吗?

kar*_*old 8 angularjs angularjs-directive

我实现了一个指令,将子内容的多个片段转换为模板.它的工作原理,但似乎比我见过的大多数例子都简单,并提出了一些关于如何进行翻译的问题.

这是指令:

module.directive('myTransclude', function() {
  return {
    restrict: 'A',
    transclude: true,
    replace: true,
    scope: true,
    template: '<div style="border: 1px solid {{color}}"><div class="my-transclude-title"></div><div class="my-transclude-body"></div></div>',
    link: function(scope, element, attrs, controller, transclude) {
      // just to check transcluded scope
      scope.color = "red";
      transclude(scope, function(clone, scope) {
        Array.prototype.forEach.call(clone, function(node) {
          if (! node.tagName) {
            return;
          }
          // look for a placeholder node in the template that matches the tag in the multi-transcluded content
          var placeholder = element[0].querySelector('.' + node.tagName.toLowerCase());
          if (! placeholder) {
            return;
          }
          // insert the transcluded content
          placeholder.appendChild(node);
        });
      });
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

这是示例用法:

<div ng-controller="AppController">
    <div my-transclude>
        <my-transclude-title> <strong ng-bind="title"></strong>

        </my-transclude-title>
        <my-transclude-body>My name is {{name}} and I've been transcluded!</my-transclude-body>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

你可以在这个小提琴中看到它的实际效果.

请注意以下几点:

  1. 它通过元素类将片段匹配到模板占位符,而不是显式定义的子指令.有什么理由这样或那样做吗?
  2. 与我见过的许多示例不同,它没有在子片段上明确使用$ compile服务.似乎Angular正在编译片段后进行翻译,至少在这个简单的情况下.这总是正确的吗?
  3. 它使用链接函数的(几乎没有记录的)transclude参数,而不是将$ transclude local注入到controller指令中的其他(几乎没有文档记录)方法.在听到如此多的告诫不操纵控制器中的DOM之后,控制器方法看起来像是一个奇怪的构造,在链接函数中处理这种情况感觉更自然.但是,我尝试了这种方式,似乎工作相同.这两者有什么区别吗?

谢谢.

编辑:为了部分回答问题#2,我发现您确实需要显式编译未应用指令的模板中克隆的已转换内容.看看这里的行为差异:http://jsfiddle.net/4tSqr/3/

Jay*_*Kan 2

要回答有关指令控制器中的 $transclude 函数与链接函数之间的差异的问题,首先我们需要了解 $transclude 函数可以通过指令编译控制器链接函数访问。

更新:根据 1.4 Angular 文档,编译(包含)已被弃用因此,只能在指令控制器链接函数中访问嵌入函数。(详细解释参见官方文档)

在编译阶段使用 $transclude 与在控制器链接阶段使用 $transclude之间存在很大差异,因为在编译阶段,您无权访问 $scope 与在控制器和链接函数中使用 $scope (controller)和范围(链接)是可访问的。话虽如此,在指令控制器中使用 $transinclude 与链接中的唯一区别是执行顺序。对于多个嵌套指令,在链接阶段使用 $transclude 相对安全,而不是在控制器中使用它。

顺序是这样的:

  1. ParentDirectiveCompile -> childDirectiveCompile(指令编译)

  2. ParentDirectiveControllerPre、parentDirectiveControllerPost -> childDirectiveControllerPre、childDirectiveControllerPost(指令控制器)

  3. childLinkFunction ->parentLinkFunction

请注意 childLinkFunction 如何在parentLinkFunction 之前先执行?(执行顺序)

有用的资源

希望这个回答能够对您有所帮助!


归档时间:

查看次数:

2172 次

最近记录:

9 年,9 月 前