115

(Angular JSのドキュメントを読んで)明らかな解決策がない、一見単純な問題があります。

DOM内のコンテナーの高さを定義するために、他のDOM要素の高さに基づいていくつかの計算を行うAngularJSディレクティブがあります。

これに似たことがディレクティブ内で起こっています:

return function(scope, element, attrs) {
    $('.main').height( $('.site-header').height() -  $('.site-footer').height() );
}

問題は、ディレクティブが実行されたときに$('site-header')見つからず、必要なjQueryでラップされたDOM要素の代わりに空の配列を返すことです。

DOMがロードされた後にのみ実行され、通常のjQueryセレクタースタイルのクエリを介して他のDOM要素にアクセスできる、ディレクティブ内で使用できるコールバックはありますか?

4

6 に答える 6

137

$('site-header')がどのように構築されているかによって異なります。

遅延なしで$timeoutの使用を試みることができます。何かのようなもの:

return function(scope, element, attrs) {
    $timeout(function(){
        $('.main').height( $('.site-header').height() -  $('.site-footer').height() );
    });        
}

それがどのように機能するかの説明:1、2

$timeoutディレクティブに挿入することを忘れないでください:

.directive('sticky', function($timeout)
于 2012-09-03T06:41:58.090 に答える
44

これが私がそれをする方法です:

app.directive('example', function() {

    return function(scope, element, attrs) {
        angular.element(document).ready(function() {
                //MANIPULATE THE DOM
        });
    };

});
于 2014-05-06T21:55:14.290 に答える
37

おそらく、作者はもう私の答えを必要としないでしょう。それでも、完全を期すために、他のユーザーがそれを役立つと思うかもしれません。最良かつ最も簡単な解決策は$(window).load()、返された関数の本体の内部で使用することです。(または、使用することもできますdocument.ready。すべての画像が必要かどうかによって異なります)。

私の謙虚な意見で使用$timeoutすることは非常に弱いオプションであり、場合によっては失敗する可能性があります。

これが私が使用する完全なコードです:

.directive('directiveExample', function(){
   return {
       restrict: 'A',
       link: function($scope, $elem, attrs){

           $(window).load(function() {
               //...JS here...
           });
       }
   }
});
于 2014-01-07T05:54:03.630 に答える
8

イベントがありngcontentloadedます、使えると思います

.directive('directiveExample', function(){
   return {
       restrict: 'A',
       link: function(scope, elem, attrs){

                $$window = $ $window


                init = function(){
                    contentHeight = elem.outerHeight()
                    //do the things
                }

                $$window.on('ngcontentloaded',init)

       }
   }
});
于 2014-01-29T02:33:15.347 に答える
5

外部リソースが原因で$timeoutを使用できず、タイミングに関する特定の問題が原因でディレクティブを使用できない場合は、ブロードキャストを使用してください。

$scope.$broadcast("variable_name_here");目的の外部リソースまたは長時間実行されるコントローラー/ディレクティブが完了した後に追加します。

次に、外部リソースが読み込まれた後、以下を追加します。

$scope.$on("variable_name_here", function(){ 
   // DOM manipulation here
   jQuery('selector').height(); 
}

たとえば、遅延HTTPリクエストの約束で。

MyHttpService.then(function(data){
   $scope.MyHttpReturnedImage = data.image;
   $scope.$broadcast("imageLoaded");
});

$scope.$on("imageLoaded", function(){ 
   jQuery('img').height(80).width(80); 
}
于 2014-05-15T21:52:43.927 に答える
1

私も同様の問題を抱えていたので、ここで解決策を共有したいと思います。

私は次のHTMLを持っています:

<div data-my-directive>
  <div id='sub' ng-include='includedFile.htm'></div>
</div>

問題:親divのディレクティブのリンク関数で、子div#subをjqueryしたかった。しかし、ディレクティブのリンク関数が実行されたときにng-includeが終了していなかったため、空のオブジェクトが表示されました。そこで、最初に$ timeoutを使用して汚い回避策を作成しました。これは機能しましたが、delay-parameterはクライアントの速度に依存していました(誰もそれを好きではありません)。

動作しますが汚れています:

app.directive('myDirective', [function () {
    var directive = {};
    directive.link = function (scope, element, attrs) {
        $timeout(function() {
            //very dirty cause of client-depending varying delay time 
            $('#sub').css(/*whatever*/);
        }, 350);
    };
    return directive;
}]);

クリーンなソリューションは次のとおりです。

app.directive('myDirective', [function () {
    var directive = {};
    directive.link = function (scope, element, attrs) {
        scope.$on('$includeContentLoaded', function() {
            //just happens in the moment when ng-included finished
            $('#sub').css(/*whatever*/);
        };
    };
    return directive;
}]);

多分それは誰かを助けます。

于 2016-09-17T20:16:41.967 に答える