2

根据角度开发人员指南:

transclude - 编译元素的内容并使其可用于指令。

内容编译时是否可以更改?出于性能原因,我想将内容传递给我想用正确的范围(父级)编译的指令,但只有当/如果某个事件发生时。那可能吗?如果没有,有没有办法我可以以不同的方式做到这一点?

4

2 回答 2

2

我这样做是为了确保在事件发生之前不会将嵌入的内容插入到 DOM 中,尽管我不能 100% 确定实际编译何时发生。它看起来像这样(使用 jQuery):

app.directive('thumbnail', function() {
  return {
    replace: true,
    transclude: true,
    template: "<div><a class='clicker'>Click to show.</a>\n" +
              "<div class='placeholder'></div></div>",
    controller: function($scope, $transclude, $element) {
      $element.find('.clicker').once('click', function() {
        $(this).hide();
        var clone = $transclude();
        $element.find('.placeholder').append(clone);
      });
    })
  };
});
<div thumbnail>
  <div expensive-dom-stuff-here></div>
</div>
于 2013-06-28T18:53:48.633 回答
0

以防其他人和我有同样的问题,我已经包含了我所做的一个简化版本。该指令是包含嵌入内容的可展开/可折叠部分。出于性能原因,它不会编译嵌入的内容,直到需要它,在这种情况下,只有当第一次扩展该部分时。展开后,内容成为 DOM 的一部分,不再需要编译/转入。该指令的大部分内容应该非常基本且易于解释,但控制器属性是我过去没有使用过的。

您还会注意到我没有使用 compile 或 link 属性。对于这个基本指令,当指令本身被编译时,我不需要进行任何 DOM 操作,因此将所有内容都粘贴在控制器中就可以了。澄清一下,指令中运行的顺序是编译、链接,然后是控制器中的任何内容。控制器使您可以访问可以在编译/链接函数中使用的所有内容,因此我将所有内容放在那里是为了简单、可读性和可维护性。

我希望这可以帮助像我这样的其他菜鸟。很高兴听到您的评论。

uiComponentsModule.directive('CollapsibleSection', ['$timeout', function($timeout) {
    return {
        restrict: 'A',
        replace: true,
        transclude: true,
        scope: {
            sectionTitle:'@',
            sectionId:'@',
            startExpanded:'@'
        },
        template:   '<div>' +
                        '<div ng-click="toggle()" class="collapsible-section-header">' +
                            '<span class="collapsible-section-title"</span>' +
                        '</div>' +
                        '<div class="collapsible-section" ng-show="isExpanded">'+
                            '<div class="transclude-me"></div>'+
                            '<div class="div-clear"></div>'+
                        '</div>' +                      
                    '</div>',
        controller: ['$scope', '$element', '$attrs', '$transclude', function (scope, element, attrs, $transclude) {
            scope.isExpanded = false;
            scope.isLoaded = false;
            scope.toggle = function(){
                if(scope.isExpanded)
                    scope.close();
                else
                {
                    scope.open();
                }
            };

            scope.showTransclude = function(){
                $transclude(function(clone) {
                    element.find(".transclude-me").append(clone);
                });
            };

            scope.open = function(){
                scope.isExpanded = true;
                if(!scope.isLoaded)
                {
                    scope.showTransclude();
                    scope.isLoaded = true;
                }
            };

            scope.close = function(){
                scope.isExpanded = false;
            };
        }]
    }
}
于 2013-06-28T21:13:47.177 回答