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

dnc*_*253 70 angularjs

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

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

我试图了解你在克隆链接功能中会做些什么.我甚至不知道哪些参数传递给它.我找到了一个示例,其中有一个参数被称为cloneHTML元素.还有其他参数吗?这究竟是哪个HTML元素?我也在考虑使用transclude: 'element'我的指令.执行这些问题的答案时,用改变'element'来代替true

我用简单的例子来理解翻译,但我似乎无法找到更复杂的例子,尤其是transclude: 'element'.我希望有人能对这一切提供更全面的解释.谢谢.

Ben*_*esh 54

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

正如@Jonah在下面指出的,这里有一篇关于指令编译选项和使用翻译功能的非常好的文章

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

这是一个更好的例子,我已经从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);
          }
        });
      };
    }
  };
});
Run Code Online (Sandbox Code Playgroud)

  • @blesh,我很高兴看到SO的一些成员更关心让事情比自我更好.谢谢你的更新! (17认同)
  • 没有汗水.我更加羞愧地认为有人遇到过那种并且学会了以错误的方式做某事*! (10认同)
  • @Jonah:你是1000%正确的.我的回答是完全错误的.这是一段时间以前,我学到了更多.无论如何,我已经完全改变了答案并将其设置为社区维基(没有获得积分). (9认同)
  • 只是对于那些来看[angular docs](http://docs.angularjs.org/api/ng.$compile)的人来说,包括一些有趣的新事物.注意:传递给编译函数的transclude函数是依赖的,因为它不知道正确的外部范围.请使用传递给链接函数的transclude函数.这是因为它预先绑定了它的范围. (4认同)
  • @blesh,我很确定这个答案是错误的.如果你打开控制台并运行你的plnk,你会看到这个错误:`TypeError:无法读取null`的属性'1'.这是因为您将一个元素传递给transcludeLinkingFn的第一个参数,并且它需要一个范围.它在文档中清楚地阐明:`transclude - 一个transclude链接函数:function(scope,cloneLinkingFn).这样的例子不是预期的用例.[本文](http://liamkaufman.com/blog/2013/05/13/understanding-angularjs-directives-part1-ng-repeat-and-compile/)显示了更好的一个. (3认同)
  • 谢谢你的回复.首先,是不是第一个进入transclude函数范围的参数?我想确保我在这里不遗漏任何东西.其次,在做`transclude:'element'时,你可以做什么来进行翻译,你不能简单地在编译函数中做任何没有任何翻译? (2认同)
  • 我真的不认为你应该将elem作为第一个参数传递 - 它确实期望一个范围. (2认同)