70

Angular docs 指令中,我看到 compile 函数有 3 个参数,其中之一是transclude. 文档提供的唯一解释是:

transclude - 一个 transclude 链接函数:function(scope, cloneLinkingFn)。

我试图了解您在克隆链接功能中究竟会做什么。我什至不知道传递了哪些参数。我发现了一个示例,它有一个名为的参数clone,它似乎是一个 HTML 元素。是否有其他可用参数?这到底是哪个 HTML 元素?我也在考虑可能transclude: 'element'在我的指令中使用。'element'使用代替时,这些问题的答案会改变true吗?

我用简单的例子来理解嵌入,但我似乎找不到更复杂的例子,尤其是transclude: 'element'. 我希望有人可以对这一切提供更彻底的解释。谢谢。

4

1 回答 1

55

编辑:完全完全改变我的答案并将其标记为“社区维基”(对我来说没有积分),因为当我回答这个问题时我完全错了

正如@Jonah 在下面指出的那样,这是一篇关于指令编译选项和使用嵌入函数的非常好的文章

基本思想是编译函数应该返回一个链接函数。您可以使用链接函数中提供的嵌入函数来克隆被嵌入的 DOM 元素,对其进行编译,然后将其插入到需要插入的任何位置。

这是我在 Plunker 上的一个更好的例子

compile 函数的想法是它让您有机会根据在创建和调用链接函数之前传递的属性以编程方式更改 DOM 元素。

// a silly directive to repeat the items of a dictionary object.
app.directive('keyValueRepeat', function ($compile){
  return {
    transclude: true,
    scope: {
      data: '=',
      showDebug: '@'
    },
    compile: function(elem, attrs, transclude) {

      if(attrs.showDebug) {                
        elem.append('<div class="debug">DEBUG ENABLED {{showDebug}}</div>');
      }

      return function(scope, lElem, lAttrs) {
        var items = [];
        console.log(lElem);
        scope.$watch('data', function(data) {

          // remove old values from the tracking array
          // (see below)
          for(var i = items.length; i-- > 0;) {
            items[i].element.remove();
            items[i].scope.$destroy();
            items.splice(i,1);
          }

          //add new ones
          for(var key in data) {

            var val = data[key],
                childScope = scope.$new(),
                childElement = angular.element('<div></div>');

            // for each item in our repeater, we're going to create it's
            // own scope and set the key and value properties on it.
            childScope.key = key;
            childScope.value = val;

            // do the transclusion.
            transclude(childScope, function(clone, innerScope) {
              //clone is a copy of the transcluded DOM element content.
              console.log(clone);

              // Because we're still inside the compile function of the directive,
              // we can alter the contents of each output item
              // based on an attribute passed.
              if(attrs.showDebug) {                
                clone.prepend('<span class="debug">{{key}}: {{value}}</span>');
              }

              //append the transcluded element.
              childElement.append($compile(clone)(innerScope));
            });

            // add the objects made to a tracking array.
            // so we can remove them later when we need to update.
            items.push({
              element: childElement,
              scope: childScope
            });

            lElem.append(childElement);
          }
        });
      };
    }
  };
});
于 2012-11-01T20:22:03.470 回答