你究竟对transclude函数和克隆链接函数做了什么?

时间:2012-11-01 18:08:02

标签: angularjs

directive Angular docs,我看到编译函数有3个参数,其中一个是transclude。文档提供的唯一解释是:

  

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

我试图了解你在克隆链接功能中究竟会做些什么。我甚至不知道哪些参数传递给它。我发现one example有一个名为clone的参数,它似乎是一个HTML元素。还有其他参数吗?这究竟是哪个HTML元素?我也在考虑在我的指令中使用transclude: 'element'。使用'element'代替true

时,这些问题的答案是否会发生变化?

我通过简单的例子理解翻译,但我似乎无法找到更复杂的例子,特别是transclude: 'element'。我希望有人能对这一切提供更全面的解释。感谢。

1 个答案:

答案 0 :(得分:53)

编辑:完全彻底改变我的回答并将其标记为“社区维基”(对我而言毫无意义)因为我在回答这个问题时完全错了

正如@Jonah在下面指出的,here is a really good article on the compile option of directives and using the transclusion function

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

Here is a better example I've pulled out of my butt on Plunker

编译函数的概念是,它使您有机会根据在创建和调用链接函数之前传递的属性以编程方式更改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);
          }
        });
      };
    }
  };
});