转换编译时间

时间:2013-06-28 16:00:35

标签: javascript angularjs

根据角度开发者指南:

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

是否可以在内容编译时进行更改?出于性能原因,我想将内容传递给我希望使用正确范围(父)编译的指令,但仅在/如果发生某个事件时。那可能吗?如果没有,有没有办法可以做到这一点呢?

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

如果其他人和我有同样的问题,我已经包含了我所做的一个愚蠢的版本。该指令是包含已转换内容的可扩展/可折叠部分。出于性能原因,它不会在需要之前编译已转换的内容,在这种情况下,只有在第一次展开该部分时才会如此。扩展后,内容将成为DOM的一部分,永远不需要再次编译/转换。这个指令的大部分应该是非常基本的和自我解释的,但控制器属性是我过去没有用过的东西。

您还会注意到我没有使用编译或链接属性。对于这个基本指令,我不需要在编译指令本身时进行任何DOM操作,因此在控制器中粘贴所有东西都很好。只是为了澄清,在指令中运行的命令是Compile,Link,然后是Controller中的任何内容。通过控制器,您可以访问编译/链接功能中可以使用的所有内容,因此我将所有内容都放在那里,以实现简单性,可读性和可维护性。

我希望这有助于像我这样的其他新手。很高兴听到您的意见。

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;
            };
        }]
    }
}