2

angular開発者ガイドによると:

transclude - 要素のコンテンツをコンパイルし、ディレクティブで利用できるようにします。

コンテンツがコンパイルされるときに変更することは可能ですか? パフォーマンス上の理由から、特定のイベントが発生した場合にのみ、正しいスコープ (親) でコンパイルしたいディレクティブにコンテンツを渡したいと考えています。それは可能ですか?そうでない場合、これを別の方法で行う方法はありますか?

4

2 に答える 2

2

実際のコンパイルがいつ行われるかは 100% 確実ではありませんが、イベントが発生するまでトランスクルージョンされたコンテンツが DOM に挿入されないようにするために、このようなことを行います。次のようになります (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 の一部になり、再度コンパイル/トランスクルージョンする必要はありません。このディレクティブのほとんどは非常に基本的で自明ですが、コントローラー属性は私が過去に使用したことがないものでした。

また、コンパイルまたはリンク属性を使用していないことにも気付くでしょう。この基本的なディレクティブについては、ディレクティブ自体がコンパイルされるときに 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 に答える