小编典典

您到底要使用transclude函数和克隆链接函数做什么?

angularjs

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

transclude-包含链接的函数:function(scope,cloneLinkingFn)。

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

我通过简单的示例理解了包含,但似乎找不到更复杂的示例,尤其是使用transclude: 'element'。我希望有人可以对此提供更详尽的解释。谢谢。


阅读 215

收藏
2020-07-04

共1个答案

小编典典

编辑:完全更改我的答案,并将其标记为“社区Wiki”(对我而言毫无意义),因为当我回答此问题时我是完全错误的

就像@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);
          }
        });
      };
    }
  };
});
2020-07-04